2016-09-20 15 views
7

Tôi sử dụng thư viện xuất sắc Python Click để xử lý các tùy chọn dòng lệnh trong công cụ của tôi. Dưới đây là một phiên bản đơn giản hóa của mã của tôi (full script here):Python Nhấp vào: thông báo lỗi tùy chỉnh

@click.command(
    context_settings = dict(help_option_names = ['-h', '--help']) 
) 
@click.argument('analysis_dir', 
       type = click.Path(exists=True), 
       nargs = -1, 
       required = True, 
       metavar = "<analysis directory>" 
) 

def mytool(analysis_dir): 
    """ Do stuff """ 

if __name__ == "__main__": 
    mytool() 

Nếu ai đó chạy lệnh mà không cần bất kỳ cờ, họ nhận được thông báo mặc định lỗi nhấp chuột:

$ mytool 

Usage: mytool [OPTIONS] <analysis directory> 

Error: Missing argument "analysis_dir". 

này là tốt đẹp, nhưng tôi Tôi rất muốn nói (rất) người dùng mới làm quen có thêm trợ giúp bằng cách sử dụng cờ trợ giúp. Nói cách khác, thêm một câu tùy chỉnh vào thông báo lỗi khi lệnh không hợp lệ yêu cầu mọi người thử dùng mytool --help để biết thêm thông tin.

Có cách nào dễ dàng để thực hiện việc này không? Tôi biết tôi có thể loại bỏ các thuộc tính required và xử lý logic này trong chức năng chính, nhưng điều đó cảm thấy loại hacky cho một bổ sung nhỏ như vậy.

+0

Tôi gặp vấn đề tương tự. Tôi muốn tự động in ra trợ giúp nếu xảy ra lỗi hoặc ít nhất hãy cho người dùng biết cách in trợ giúp. Nếu không, chúng ta phải giả định rằng mọi người sử dụng công cụ của chúng tôi đều quen thuộc với tư duy dựa trên unix. Tôi thích bấm cho đến nay nhưng tôi chán nản rằng câu hỏi này chưa được trả lời, bởi vì tôi muốn một cái gì đó sẽ giúp xây dựng các công cụ mà người mới có thể dễ dàng sử dụng. – user1677663

+0

Chỉ tìm thấy điều này, có thể là một giải pháp: http://stackoverflow.com/questions/35642202/python-click-return-the-helper-menu – user1677663

+0

Không, điều đó không hiệu quả. – user1677663

Trả lời

3

Xây dựng thư cho hầu hết các lỗi trong nhấp chuột python được xử lý bằng phương thức hiển thị của lớp UsageError: click.exceptions.UsageError.show.

Vì vậy, nếu bạn xác định lại phương pháp này, bạn sẽ có thể tạo thông báo lỗi tùy chỉnh của riêng mình. Dưới đây là một ví dụ về một tùy biến mà gắn thêm menu trợ giúp cho bất kỳ thông báo lỗi mà câu trả lời này SO question:

def modify_usage_error(main_command): 
    ''' 
     a method to append the help menu to an usage error 

    :param main_command: top-level group or command object constructed by click wrapper 
    :return: None 
    ''' 

    from click._compat import get_text_stderr 
    from click.utils import echo 
    def show(self, file=None): 
     import sys 
     if file is None: 
      file = get_text_stderr() 
     color = None 
     if self.ctx is not None: 
      color = self.ctx.color 
      echo(self.ctx.get_usage() + '\n', file=file, color=color) 
     echo('Error: %s\n' % self.format_message(), file=file, color=color) 
     sys.argv = [sys.argv[0]] 
     main_command() 

    click.exceptions.UsageError.show = show 

Khi bạn xác định lệnh chính của bạn, bạn có thể sau đó chạy kịch bản sửa đổi:

import click 
@click.group() 
def cli(): 
    pass 

modify_usage_error(cli) 

Tôi chưa khám phá liệu có các lời gọi thời gian chạy của ClickException ngoài lỗi sử dụng hay không. Nếu có, sau đó bạn có thể cần phải sửa đổi xử lý lỗi tùy chỉnh của bạn để kiểm tra đầu tiên rằng ctx là một thuộc tính trước khi bạn thêm dòng click.exceptions.ClickException.show = show vì nó không xuất hiện rằng ClickException được cấp ctx lúc khởi tạo.

+0

Tuyệt vời, cảm ơn RJ! Điều này làm việc hoàn hảo với một ngoại lệ - tôi đã phải loại bỏ hàm gọi hàm cuối cùng thành 'main_command()' vì điều này gây ra lỗi đệ quy. – tallphil

+0

Điều này cảm thấy tốt! https://github.com/ewels/MultiQC/commit/62cc60 Tôi đã có một mức độ thấp của sự khó chịu về việc không thể làm điều này trong bảy tháng nay! Cảm ơn một lần nữa! – tallphil

Các vấn đề liên quan