Argparse: Cách bao gồm các giá trị mặc định trong '--help'?


307

Giả sử tôi có đoạn trích argparse sau:

diags.cmdln_parser.add_argument( '--scan-time',
                     action  = 'store',
                     nargs   = '?',
                     type    = int,
                     default = 5,
                     help    = "Wait SCAN-TIME seconds between status checks.")

Hiện tại, --helptrả về:

usage: connection_check.py [-h]
                             [--version] [--scan-time [SCAN_TIME]]

          Test the reliability/uptime of a connection.



optional arguments:
-h, --help            show this help message and exit
--version             show program's version number and exit
--scan-time [SCAN_TIME]
                    Wait SCAN-TIME seconds between status checks.

Tôi thích cái gì đó như:

--scan-time [SCAN_TIME]
                    Wait SCAN-TIME seconds between status checks.
                    (Default = 5)

Nhìn trộm mã định dạng trợ giúp tiết lộ các tùy chọn hạn chế. Có một cách thông minh argparseđể in giá trị mặc định --scan-timetheo cách tương tự, hay tôi chỉ nên phân lớp trình helpđịnh dạng?


5
Bạn có thể quan tâm đến docopt . Tôi chưa bao giờ nhìn argparse lần nữa.
Paulo Scardine

14
@PauloScardine - Được tích hợp vào ngôn ngữ là một lợi ích chính cho argparse.
jordanm

1
@PauloScardine: Kéo một thư viện không chuẩn vào dự án hiện tại của tôi thực sự sẽ là một nỗi đau, nhưng tôi chắc chắn giống như giao diện của đầu ra của docopt. Cảm ơn vì tiền hỗ trợ!
JS.

@JS. bạn nói "Kéo một thư viện không chuẩn vào dự án hiện tại của tôi thực sự sẽ là một nỗi đau" Thật sao? Có rất nhiều thư viện rất hữu ích tại pypi. Trong bối cảnh của tôi, thật dễ dàng để kéo vào một thư viện không chuẩn. Thật đáng buồn, nếu nó khó trong bối cảnh của bạn.
guettli

3
@guettli: Dự án đó là cho một dự án nhúng thương mại. Bạn cài đặt đúng là dễ dàng. Nhận được sự chấp thuận từ pháp lý của công ty là một cơn ác mộng.
JS.

Câu trả lời:


447

Sử dụng argparse.ArgumentDefaultsHelpFormatterđịnh dạng :

parser = argparse.ArgumentParser(
    # ... other options ...
    formatter_class=argparse.ArgumentDefaultsHelpFormatter)

Để trích dẫn tài liệu:

Lớp định dạng khác có sẵn, ArgumentDefaultsHelpFormattersẽ thêm thông tin về giá trị mặc định của từng đối số.

Lưu ý rằng điều này chỉ áp dụng cho các đối số có văn bản trợ giúp được xác định ; không có helpgiá trị cho một cuộc tranh cãi, không có thông báo trợ giúp để thêm thông tin về giá trị mặc định để .

Đầu ra chính xác cho tùy chọn thời gian quét của bạn sau đó trở thành:

  --scan-time [SCAN_TIME]
                        Wait SCAN-TIME seconds between status checks.
                        (default: 5)

12
Tôi có thể kiểm soát chỉ các đối số có default=hiển thị giá trị mặc định không? Vì tôi không thích các văn bản 'mặc định: Không'.
ziyuang

14
Bạn có thể thiết lập defaultđể SUPPRESS: default=argparse.SUPPRESS. Lưu ý rằng trong trường hợp đó không có thuộc tính sẽ được bổ sung vào kết quả namespace nếu lập luận rằng đã bỏ qua, xem các defaulttài liệu hướng dẫn .
Martijn Pieters

4
Lưu ý rằng bạn cũng cần chỉ định điều này cho mỗi subparser được tạo.
KomodoDave

1
Sau đó tạo một câu hỏi mới, bao gồm một ví dụ tái tạo tối thiểu thể hiện vấn đề. Như tôi đã nói, nó hoạt động với tôi với Python 2.7.
Martijn Pieters

3
@David Mình cũng gặp vấn đề tương tự. Thêm helpđối số trong add_argumentvà điều đó sẽ làm việc.
Pablo Díaz Ogni

190

Thêm vào '%(default)s'tham số trợ giúp để kiểm soát những gì được hiển thị.

parser.add_argument("--type", default="toto", choices=["toto","titi"],
                              help = "type (default: %(default)s)")

9
Tôi thích tùy chọn này vì tôi đã sử dụng format_group = argparse.RawTestHelpFormatter và không cảm thấy muốn xì hơi với OOP.
mqsoh

23
Đừng quên bao gồm biến 'loại' trong chuỗi định dạng của bạn-- ví dụ '% (mặc định) s' cho một chuỗi hoặc '% (mặc định) d' cho một chữ số.
strongMA

1
Tôi thích giải pháp này tốt hơn nhiều, nó đơn giản hơn nhiều và tôi không phải xử lý rõ ràng các đối số không có giá trị mặc định.
void.pulum

@mqsoh nhiều kế thừa thực sự chỉ hoạt động, nhưng tiếc là API không công khai: stackoverflow.com/a/52025430/895245
Ciro Santilli 冠状 六四 事件 26/8/18

1
Tôi thích điều này bởi vì việc thay đổi lớp định dạng sẽ thêm một loạt "(mặc định: Không)" ở mọi nơi đang làm lộn xộn sự trợ giúp.
6005

11

Lớp bọc

Đây là cách tiếp cận DRY và đáng tin cậy nhất mà tôi đã tìm thấy cho đến nay để hiển thị mặc định và sử dụng một định dạng khác như argparse.RawTextHelpFormattercùng một lúc:

#!/usr/bin/env python3

import argparse

class ArgumentParserWithDefaults(argparse.ArgumentParser):
    def add_argument(self, *args, help=None, default=None, **kwargs):
        if help is not None:
            kwargs['help'] = help
        if default is not None and args[0] != '-h':
            kwargs['default'] = default
            if help is not None:
                kwargs['help'] += ' Default: {}'.format(default)
        super().add_argument(*args, **kwargs)

parser = ArgumentParserWithDefaults(
    formatter_class=argparse.RawTextHelpFormatter
)
parser.add_argument('-a', default=13, help='''my help
for a''')
parser.add_argument('-b', default=42, help='''my help
for b''')
parser.add_argument('--no-default', help='''my help
for no-default''')
parser.add_argument('--no-help', default=101)

parser.print_help()
print()
print(parser.parse_args())

Đầu ra:

usage: main.py [-h] [-a A] [-b B] [--no-default NO_DEFAULT]
               [--no-help NO_HELP]

optional arguments:
  -h, --help            show this help message and exit
  -a A                  my help
                        for a Default: 13
  -b B                  my help
                        for b Default: 42
  --no-default NO_DEFAULT
                        my help
                        for no-default
  --no-help NO_HELP

Namespace(a=13, b=42, no_default=None, no_help=101)

ArgumentDefaultsHelpFormatter+ RawTextHelpFormatterthừa kế nhiều

Nhiều kế thừa chỉ hoạt động, nhưng dường như không phải là API công khai:

#!/usr/bin/env python3

import argparse

class RawTextArgumentDefaultsHelpFormatter(
        argparse.ArgumentDefaultsHelpFormatter,
        argparse.RawTextHelpFormatter
    ):
        pass

parser = argparse.ArgumentParser(
    formatter_class=RawTextArgumentDefaultsHelpFormatter
)
parser.add_argument('-a', default=13, help='''my help
for a''')
parser.add_argument('-b', default=42, help='''my help
for b''')
parser.print_help()

Đầu ra:

usage: a.py [-h] [-a A] [-b B]

optional arguments:
  -h, --help  show this help message and exit
  -a A        my help
              for a (default: 13)
  -b B        my help
              for b (default: 42)

Nó chỉ hoạt động hiệu quả vì như chúng ta có thể thấy một cách tầm thường từ các nguồn https://github.com/python/cpython/blob/v3.6.5/Lib/argparse.py#L648 rằng:

  • RawTextHelpFormatter thực hiện _split_lines
  • ArgumentDefaultsHelpFormatter thực hiện _get_help_string

vì vậy chúng tôi có thể đoán rằng họ sẽ làm việc tốt với nhau.

Tuy nhiên, đây dường như không phải là API công khai và cũng không phải là phương pháp formatter_class, vì vậy tôi không nghĩ rằng hiện tại có một cách API công khai để thực hiện. argparsedocopes nói:

Tất cả các lớp khác trong mô-đun này được coi là chi tiết thực hiện. (Cũng lưu ý rằng HelpFormatter và RawDescripHelpFormatter chỉ được coi là công khai dưới dạng tên đối tượng - API của các đối tượng định dạng vẫn được coi là một chi tiết triển khai.)

Xem thêm: Tùy chỉnh thông báo trợ giúp argparse

Đã thử nghiệm trên Python 3.6.5.


1
Tuyệt quá ! Cuối cùng có cả hai chuỗi định dạng được định dạng và các đối số mặc định được in. Cảm ơn
Sylvain
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.