【问题标题】:Python argparse help option won't display all of the arguments when using parse_known_args()Python argparse 帮助选项在使用 parse_known_args() 时不会显示所有参数
【发布时间】:2021-09-04 00:36:52
【问题描述】:

基本上,我有一个程序接受一些可选/位置参数,但我想要一个可以单独使用的可选参数。我希望它的工作方式类似于“--version”选项的工作方式,如果给出该参数,则不需要位置参数并且代码运行。

我制作了几个测试文件来说明我的意思:

import argparse
import os,sys

def main():
    parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    
    parser.add_argument("--print-line", type=str, metavar="file", help="print the first line of a file")
    parser.add_argument("num", type=int, help="an important number")
    
    args = parser.parse_args()

    if args.print_line is not None:
        if not os.path.isfile(args.print_line):
            parser.error("file:%s not found" % args.print_line)
        with open(args.print_line, "r") as infile:
            print("First line:\n%s" % infile.readline().rstrip())
        return
    
    print("Important number: %i" % args.num)
    
    
if __name__ == "__main__":
    main()

帮助选项给出:

usage: notworks_goodhelp.py [-h] [--print-line file] num

positional arguments:
  num                an important number

optional arguments:
  -h, --help         show this help message and exit
  --print-line file  print the first line of a file (default: None)

这是完美的!但是,如果我尝试使用可选参数,

$ python notworks_goodhelp.py --print-line file.txt 
usage: notworks_goodhelp.py [-h] [--print-line file] num
notworks_goodhelp.py: error: too few arguments

它不起作用,因为它缺少位置参数。

我使用parse_known_args() 使脚本工作,但是帮助屏幕出错了!如下图:

import argparse
import os,sys

def main():
    parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    
    parser.add_argument("--print-line", type=str, metavar="file", help="print the first line of a file")
    args, leftovers = parser.parse_known_args()
    
    if args.print_line is not None:
        if not os.path.isfile(args.print_line):
            parser.error("file:%s not found" % args.print_line)
        with open(args.print_line, "r") as infile:
            print("First line:\n%s" % infile.readline().rstrip())
        return
    
    parser.add_argument("num", type=int, help="an important number")
    args = parser.parse_args(leftovers)
    
    print("Important number: %i" % args.num)
    
    
if __name__ == "__main__":
    main()

但帮助屏幕是:

usage: works_nohelp.py [-h] [--print-line file]

optional arguments:
  -h, --help         show this help message and exit
  --print-line file  print the first line of a file (default: None)

缺少 'num' 位置参数!

有人知道解决这个问题的方法吗?

【问题讨论】:

  • --version 有效,因为它绑定到version 操作,该操作立即输出版本并退出脚本,而不是等到所有选项都被解析后。您可以对--print_line 执行相同的操作:定义argparse.Action 的自定义子类,在解析选项时执行您想要的操作,而不是等到解析完所有 选项。
  • 第一个parse_argsparse_known_args看到help(或版本)并行动。
  • 啊,我明白了。我要试试argparse.Action方法。

标签: python argparse


【解决方案1】:

根据chepner 的评论,我能够通过适当的操作和帮助屏幕使其在该程序中运行。谢谢!

import argparse
import os,sys

class ExitOnAction(argparse.Action):
    def __init__(self, option_strings, dest, nargs=None, **kwargs):
        if nargs != 1 and nargs is not None:
            print("nargs: " + str(nargs))
            raise ValueError("nargs must be 1")
        super(ExitOnAction, self).__init__(option_strings, dest, **kwargs)
    
    def __call__(self, parser, namespace, values, option_string=None):
        setattr(namespace, self.dest, values)
        if not os.path.isfile(values):
            parser.error("file:%s not found" % values)
        with open(values, "r") as infile:
            print("First line:\n%s" % infile.readline().rstrip())
            sys.exit()
        
        

def main():
    parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    
    parser.add_argument("--print-line", action=ExitOnAction, type=str, metavar="file", help="print the first line of a file")
    parser.add_argument("num", type=int, help="an important number")
    
    print("Parsing args")
    args = parser.parse_args()
    print("Parsed args")
    '''
    if args.print_line is not None:
        if not os.path.isfile(args.print_line):
            parser.error("file:%s not found" % args.print_line)
        with open(args.print_line, "r") as infile:
            print("First line:\n%s" % infile.readline().rstrip())
        return
    '''
    print("Important number: %i" % args.num)
    
    
if __name__ == "__main__":
    main()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-24
    • 1970-01-01
    • 2019-03-16
    • 1970-01-01
    相关资源
    最近更新 更多