2012-06-17 26 views
14

Tôi đang viết một tiện ích dòng lệnh bằng Argparse và đã thêm một loạt các sub_parsers (các lệnh phụ). Trong menu trợ giúp chúng xuất hiện dưới một nhóm được gọi là "lệnh" và tôi nhận được một danh sách tốt đẹp của tất cả các tùy chọn có thể. Tuy nhiên trước khi danh sách này xuất hiện, tất cả các lệnh giống nhau xuất hiện dưới tiêu đề nhóm trong dấu ngoặc ôm như vậy:Trăn Argparse, xóa danh sách người đăng ký trong menu trợ giúp

Commands: 
    {foo, bar} 

    foo   - foo does foo 
    bar   - bar does bar 

Tôi muốn xóa các mục nhập thừa xuất hiện trong niềng răng. Nó chỉ xuất hiện trong nhóm này chứa đầy sub_parsers.

Mã của tôi để xử lý này trông giống như vậy: (nơi phân tích cú pháp là ArgumentParser() Ví dụ)

subparsers = parser.add_subparsers(title="Commands") 

foo = subparsers.add_parser("foo", help="- foo does foo") 
bar = subparsers.add_parser("bar", help="- bar does bar") 

Tôi đã xem xét các thuộc tính và phương pháp của nhóm lệnh hành động của tôi và dường như không thể tìm thấy bất cứ điều gì mà sẽ giải quyết điều này cho tôi (ít nhất là từ những gì tôi có thể làm cho tinh thần). Tôi không chắc liệu có ai khác đã giải quyết vấn đề này không, tôi nhận ra nó có thể hơi mơ hồ. Và một lần nữa, tất cả những gì tôi đang cố làm là tìm cách xóa danh sách dư thừa các lệnh xuất hiện trong niềng răng.

Trả lời

11

Các "{foo, thanh}" một phần là lập luận 'metavar'. Một metavar là cách argparse đề cập đến các giá trị đối số dự kiến ​​trong chuỗi sử dụng và trợ giúp. argparse xử lý các subcommands như một đối số với nhiều lựa chọn vì vậy nếu bạn không chỉ định một metavar, mặc định là danh sách các lựa chọn (subcommands) trong các dấu ngoặc nhọn. Nó cho phép người dùng biết các tùy chọn có thể cho các tiểu ban, nhưng kể từ khi chúng được liệt kê ngay dưới đây, nó dư thừa và nếu bạn có nhiều tiểu ban, nó xấu xí.

Bạn có thể dễ dàng thay thế với metavar chọn của riêng bạn:

subparsers = parser.add_subparsers(title="Commands", metavar="<command>") 
+0

Hoàn hảo, chính xác những gì tôi cần! Cảm ơn. –

+0

Vẫn không thể xóa hoàn toàn tiêu đề đó. 'argparse' để trống dòng. –

+1

@anatolytechtonik Xem phần hack của tôi bên dưới. – Naitree

3

Bạn có thể tùy chỉnh định dạng thông báo trợ giúp của mình bằng cách viết lớp trình định dạng của riêng mình, dựa trên giao diện của argparse.HelpFormatter và chuyển giao nó tới hàm tạo của trình phân tích cú pháp bằng cách sử dụng đối số formatter_class.

Để biết thêm chi tiết, xem http://docs.python.org/dev/library/argparse.html#formatter-class

1

Sau khi lặn thực sự sâu vào mã nguồn argparse, tôi đã xây dựng một Hack để loại bỏ các dư thừa danh sách {cmd1,...} lựa chọn.

Hack thực hiện trình định dạng trợ giúp tùy chỉnh để sửa đổi các phương thức định dạng của HelpFormatter khi giao dịch với hành động của người đăng ký . Cụ thể, nó loại bỏ subparsers metavarhelp dòng trong nhóm đối số tiểu nhóm và loại bỏ thêm thụt đầu dòng của các tiểu ban đó.

Vui lòng sử dụng cẩn thận.

Các python 3 phiên bản, thử nghiệm với python3.6

from argparse import ArgumentParser, HelpFormatter, _SubParsersAction 

class NoSubparsersMetavarFormatter(HelpFormatter): 

    def _format_action(self, action): 
     result = super()._format_action(action) 
     if isinstance(action, _SubParsersAction): 
      # fix indentation on first line 
      return "%*s%s" % (self._current_indent, "", result.lstrip()) 
     return result 

    def _format_action_invocation(self, action): 
     if isinstance(action, _SubParsersAction): 
      # remove metavar and help line 
      return "" 
     return super()._format_action_invocation(action) 

    def _iter_indented_subactions(self, action): 
     if isinstance(action, _SubParsersAction): 
      try: 
       get_subactions = action._get_subactions 
      except AttributeError: 
       pass 
      else: 
       # remove indentation 
       yield from get_subactions() 
     else: 
      yield from super()._iter_indented_subactions(action) 

parser = ArgumentParser(formatter_class=NoSubparsersMetavarFormatter) 
subparsers = parser.add_subparsers(title="Commands") 

foo = subparsers.add_parser("foo", help="- foo does foo") 
bar = subparsers.add_parser("bar", help="- bar does bar") 

parser.parse_args(['-h']) 

Phiên bản python 2, thử nghiệm với python2.7

from argparse import ArgumentParser, HelpFormatter, _SubParsersAction 

class NoSubparsersMetavarFormatter(HelpFormatter): 

    def _format_action(self, action): 
     result = super(NoSubparsersMetavarFormatter, 
         self)._format_action(action) 
     if isinstance(action, _SubParsersAction): 
      return "%*s%s" % (self._current_indent, "", result.lstrip()) 
     return result 

    def _format_action_invocation(self, action): 
     if isinstance(action, _SubParsersAction): 
      return "" 
     return super(NoSubparsersMetavarFormatter, 
        self)._format_action_invocation(action) 

    def _iter_indented_subactions(self, action): 
     if isinstance(action, _SubParsersAction): 
      try: 
       get_subactions = action._get_subactions 
      except AttributeError: 
       pass 
      else: 
       for subaction in get_subactions(): 
        yield subaction 
     else: 
      for subaction in super(NoSubparsersMetavarFormatter, 
            self)._iter_indented_subactions(action): 
       yield subaction 

parser = ArgumentParser(formatter_class=NoSubparsersMetavarFormatter) 
subparsers = parser.add_subparsers(title="Commands") 

foo = subparsers.add_parser("foo", help="- foo does foo") 
bar = subparsers.add_parser("bar", help="- bar does bar") 

parser.parse_args(['-h']) 

Mẫu đầu ra:

usage: a.py [-h] {foo,bar} ... 

optional arguments: 
    -h, --help show this help message and exit 

Commands: 
    foo   - foo does foo 
    bar   - bar does bar 
+1

Tôi đã làm điều đó tương tự như vậy - http://techtonik.rainforce.org/2016/11/help-formatting-problem-with-argparse.html - và tôi nghĩ rằng cách thích hợp cho nỗi đau 'arparse' là xuất tất cả dữ liệu của nó trong một bước và sau đó chỉ định dạng dữ liệu này thay vì gọi rất nhiều hack. –

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