【问题标题】:Python: argparse optional arguments without dashesPython:没有破折号的 argparse 可选参数
【发布时间】:2012-07-03 20:50:00
【问题描述】:

我想要以下语法:

python utility.py file1 FILE1 file2 FILE2

其中 file1 和 file2 是可选参数。 使用这种语法很简单:

python utility.py --file1 FILE1 --file2 FILE2

使用

parser.add_argument('--file1',type=file)
parser.add_argument('--file2',type=file)

但是,如果我删除破折号,argparse 开始将其解释为位置参数而不是可选参数...

换句话说,是否可以明确告诉 argparse 参数是可选的还是位置的,这样我就可以在没有破折号的情况下使用可选参数?

【问题讨论】:

  • 这种语法(没有破折号)简直令人困惑!约定存在是有原因的。
  • @MartijnPieters:反例:gitsvn 命令行界面。
  • @RodyOldenhuis:这些是子命令,而不是开关。每个子命令都有选项,使用破折号。
  • @MartijnPieters:这只是语义,从语法的角度来看没有区别 - 没有破折号的参数。 argparse 不(直接)支持任何语义。顺便说一句,在我的示例中它们也不是开关(但这与我刚才提到的无关)。
  • @jvm:子命令通常不共享开关。有一个共享级别 (git --version) 和每个子命令开关 (git checkout --patch)。不要在这里忽略语义。

标签: python argparse optional-arguments


【解决方案1】:

没有办法让argparse 为您执行此操作。但是,您可以让 argparse 接受任意数量的位置参数:

parser.add_argument('FILES',nargs='*')
options=parser.parse_args()
file1,optional_files=options.FILES[0],options.FILES[1:]

当然,您可能需要添加一些检查以确保至少提供了 1 个文件,等等。

编辑

我仍然不能 100% 确定你想要什么,但如果 file1file2 是文字字符串,你可以通过预处理 sys.argv 来解决这个问题。当然,这仍然会奇怪地格式化您的帮助消息,但您始终可以添加一个结语,说明任何一种形式都可以:

import argparse
import sys

mangle_args=('file1','file2')
arguments=['--'+arg if arg in mangle_args else arg for arg in sys.argv[1:]]

parser=argparse.ArgumentParser()
parser.add_argument('--file1')
parser.add_argument('--file2')
options=parser.parse_args(arguments)

【讨论】:

  • 位置参数对我来说是不够的。比如file1可以跳过,file2输入,file3跳过,file4输入,赋值很重要(即我需要知道用户指定的是file2和file4)
  • @jvm -- argparse(或任何东西)应该如何知道您提供的文件是 file2 而不是 file1?如果你不能从它在命令行中的顺序来排序,当然argparse 也做不到。
  • file1file2 常量字符串,还是它们的文件名——也许这就是我在这里不理解的......
  • @jvm -- 我想我现在明白你想要做什么了。我已经发布了一个“解决方法”。它有点难看,但对于您的目的来说可能已经足够了。
  • 谢谢,这确实是一个可行的解决方案。我希望我错过了一些可以直接允许我这样做的 argparse 函数,但如果这不可能,那么你的解决方法可能是最好的。只是一些吹毛求疵 - 当然您还需要在示例中导入 argparse。
【解决方案2】:

另一个例子是:

train.py

import argparse
if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="Arguments for wake_word")
    parser.add_argument('data', type=str, help="path to data")
    parser.add_argument('output', type=str, help="model save path")
    parser.add_argument('batch_size', type=int, help="batch size")
    parser.add_argument('epochs', type=int, help="no.s of epochs")
    args = parser.parse_args()
print(args.data + args.output + args.batch_size + args.epochs)

那么您可以只使用不带破折号的参数运行此代码

train.py /path/to/data/ /path/to/output_files/ 128 100

并且,按升序排列

【讨论】:

    【解决方案3】:

    有同样的问题。我的解决方法是:

    lastarg = sys.argv[-1]
    if len(sys.argv) > 1 and lastarg[0] != '-':
        sys.argv[-1] = '-file'
        sys.argv.append(lastarg)
    
    argparser = argparse.ArgumentParser()
    argparser.add_argument('-d', action='store_true')
    argparser.add_argument('-nrv', action='store_true')
    argparser.add_argument('-file', type=str, default='')
    args = argparser.parse_args()
    

    【讨论】:

      猜你喜欢
      • 2021-05-06
      • 2019-03-09
      • 2018-04-22
      • 1970-01-01
      • 2020-11-25
      • 2015-09-16
      • 1970-01-01
      • 2014-09-15
      • 2012-10-01
      相关资源
      最近更新 更多