อาร์กิวเมนต์: วิธีรวมค่าเริ่มต้นใน '--help' หรือไม่


307

สมมติว่าฉันมีตัวอย่างอาร์กิวเมนต์ต่อไปนี้:

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

ปัจจุบัน--helpส่งคืน:

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.

ฉันต้องการของที่ชอบ:

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

การดูที่โค้ดตัวจัดรูปแบบความช่วยเหลือพบตัวเลือกที่ จำกัด มีวิธีที่ชาญฉลาดในการargparseพิมพ์ค่าเริ่มต้นสำหรับ--scan-timeในลักษณะที่คล้ายกันหรือฉันควร subclass helpformatter?


5
คุณอาจจะสนใจในdocopt ฉันไม่เคยดูการโต้แย้งอีกเลย
เปาโล Scardine

14
@PauloScardine - การสร้างขึ้นในภาษาเป็นประโยชน์ที่สำคัญสำหรับการโต้แย้ง
จอร์แดน

1
@PauloScardine: การดึงไลบรารี่ที่ไม่ได้มาตรฐานลงในโปรเจคปัจจุบันของฉันจะเป็นเรื่องที่เจ็บปวด แต่ฉันแน่ใจว่าหน้าตาของ docopt เอาท์พุท ขอบคุณสำหรับทิป!
JS

@JS คุณพูดว่า "การดึงไลบรารี่ที่ไม่ได้มาตรฐานในโครงการปัจจุบันของฉันจะทำให้เจ็บปวด" จริงหรือ pypi มีห้องสมุดที่มีประโยชน์มากมาย ในบริบทของฉันมันเป็นเรื่องง่ายที่จะดึงในห้องสมุดที่ไม่ได้มาตรฐาน มันเศร้าถ้ามันยากในบริบทของคุณ
guettli

3
@guettli: โครงการนั้นมีไว้สำหรับโครงการฝังตัวในเชิงพาณิชย์ คุณติดตั้งถูกต้องเป็นเรื่องง่าย การได้รับการอนุมัติจากกฎหมาย บริษัท นั้นเป็นฝันร้าย
JS

คำตอบ:


447

ใช้ตัวargparse.ArgumentDefaultsHelpFormatterจัดรูปแบบ :

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

ในการอ้างถึงเอกสาร:

คลาสตัวจัดรูปแบบอื่นที่พร้อมใช้งานArgumentDefaultsHelpFormatterจะเพิ่มข้อมูลเกี่ยวกับค่าเริ่มต้นของแต่ละอาร์กิวเมนต์

โปรดทราบว่านี้ใช้เฉพาะกับข้อโต้แย้งที่มีข้อความช่วยเหลือที่กำหนดไว้ ; โดยไม่มีhelpค่าสำหรับอาร์กิวเมนต์ไม่มีข้อความช่วยเหลือในการเพิ่มข้อมูลเกี่ยวกับค่าเริ่มต้นที่จะ

ผลลัพธ์ที่แน่นอนสำหรับตัวเลือกเวลาสแกนของคุณจะกลายเป็น:

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

12
ฉันสามารถควบคุมได้เพียงข้อโต้แย้งที่มีการdefault=แสดงค่าเริ่มต้นอย่างชัดเจนหรือไม่ เนื่องจากฉันไม่ชอบข้อความ 'เริ่มต้น: ไม่มี'
ziyuang

14
คุณสามารถตั้งค่าdefaultเพื่อ:SUPPRESS default=argparse.SUPPRESSทราบว่าในกรณีที่ไม่มีแอตทริบิวต์จะถูกเพิ่มลงผล namespace ถ้าอาร์กิวเมนต์ที่ถูกมองข้ามเห็นเอกสาร default
Martijn Pieters

4
โปรดทราบว่าคุณต้องระบุสิ่งนี้สำหรับตัวแยกย่อยแต่ละอันที่สร้างขึ้นเช่นกัน
KomodoDave

1
จากนั้นสร้างคำถามใหม่รวมถึงตัวอย่างที่จำลองได้น้อยที่สุดซึ่งแสดงให้เห็นถึงปัญหา อย่างที่ฉันพูดมันใช้งานได้กับ Python 2.7
Martijn Pieters

3
@ David ฉันมีปัญหาเดียวกัน เพิ่มhelpอาร์กิวเมนต์ในadd_argumentและที่ควรจะทำงาน
Pablo Díaz Ogni

190

เพิ่ม'%(default)s'ไปยังพารามิเตอร์วิธีใช้เพื่อควบคุมสิ่งที่จะแสดง

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

9
ฉันชอบตัวเลือกนี้เพราะฉันได้ใช้ format_class = argparse.RawTestHelpFormatter แล้วและไม่รู้สึกอยากผายลมกับ OOP
mqsoh

23
อย่าลืมใส่ตัวแปร 'type' ในสตริงการจัดรูปแบบของคุณเช่น '% (ค่าเริ่มต้น) s' สำหรับสตริงหรือ '% (ค่าเริ่มต้น) d' เป็นตัวเลข
strongMA

1
ฉันชอบวิธีนี้ดีกว่ามากมันง่ายกว่ามากและฉันไม่ต้องจัดการกับข้อโต้แย้งอย่างชัดเจนโดยไม่มีค่าเริ่มต้น
void.pointer

@mqsoh การสืบทอดหลายรายการใช้งานได้จริง แต่น่าเสียดายที่ไม่ใช่ API สาธารณะ: stackoverflow.com/a/52025430/895245
Ciro Santilli 郝海东冠状病病六四事件法轮功

1
ฉันชอบสิ่งนี้เพราะการเปลี่ยนคลาสของตัวจัดรูปแบบเพิ่มกลุ่มของ "(ค่าเริ่มต้น: ไม่มี)" ทุกที่ที่ช่วยให้รก
6005

11

คลาส Wrapper

นี่เป็นวิธีที่เชื่อถือได้และแห้งที่สุดที่ฉันเคยพบมาเพื่อแสดงค่าเริ่มต้นและใช้ตัวจัดรูปแบบอื่นเช่นargparse.RawTextHelpFormatterในเวลาเดียวกัน:

#!/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())

เอาท์พุท:

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+ RawTextHelpFormatterการสืบทอดหลายรายการ

การสืบทอดหลายรายการใช้งานได้ แต่ดูเหมือนจะไม่ใช่ API สาธารณะ:

#!/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()

เอาท์พุท:

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)

มันใช้งานได้เพราะเราสามารถเห็นได้จากแหล่งhttps://github.com/python/cpython/blob/v3.6.5/Lib/argparse.py#L648ที่:

  • RawTextHelpFormatter การดำเนินการ _split_lines
  • ArgumentDefaultsHelpFormatter การดำเนินการ _get_help_string

ดังนั้นเราสามารถเดาได้ว่าพวกเขาจะทำงานร่วมกันได้ดี

อย่างไรก็ตามนี่ดูเหมือนจะไม่เป็น API สาธารณะและไม่ใช่วิธีการformatter_classดังนั้นฉันจึงไม่คิดว่าจะมีวิธี API สาธารณะในการดำเนินการในปัจจุบัน argparsedocstring พูดว่า:

คลาสอื่น ๆ ทั้งหมดในโมดูลนี้จะพิจารณารายละเอียดการใช้งาน (โปรดทราบว่า HelpFormatter และ RawDescriptionHelpFormatter นั้นจะถือว่าเป็นชื่อสาธารณะเท่านั้น - API ของวัตถุของตัวจัดรูปแบบยังถือว่าเป็นรายละเอียดการใช้งาน)

ดูเพิ่มเติม: ปรับแต่งข้อความช่วยเหลือ argparse

ทดสอบกับ Python 3.6.5


1
เยี่ยมมาก! ในที่สุดก็มีทั้งรูปแบบ docstring และอาร์กิวเมนต์เริ่มต้นที่พิมพ์ ขอบคุณ
Sylvain
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.