假设我有一个argparse python脚本:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--foo", required=True)
现在我想添加另一个选项--bar,它默认将“_BAR”附加到--foo参数指定的任何内容。
我的目标:
>>> parser.parse_args(['--foo', 'FOO'])
>>> Namespace(foo='FOO', bar="FOO_BAR")
和
>>> parser.parse_args(['--foo', 'FOO', '--bar', 'BAR'])
>>> Namespace(foo='FOO', bar="BAR")
我需要这样的东西:
parser.add_argument("--bar", default=get_optional_foo + "_BAR")
答案 0 :(得分:14)
作为第一次尝试,我会使用after-argparse函数来实现这一点。
def addbar(args):
if args.bar is None:
args.bar = args.foo+'_BAR'
如果需要在help
中反映此操作,请自行将其放在那里。
理论上,您可以为Action
编写一个自定义foo
,用于设置bar
值的值。但这需要更加熟悉Action
类。
我尝试了一个自定义Action
来调整default
行为的bar
,但这很棘手。 parse_args
在开始之前使用默认值,然后才对任何参数起作用。
答案 1 :(得分:5)
这是另一次尝试编写自定义Action类
import argparse
class FooAction(argparse.Action):
# adapted from documentation
def __call__(self, parser, namespace, values, option_string=None):
setattr(namespace, self.dest, values)
defaultbar = getattr(namespace, 'bar')
try:
defaultbar = defaultbar%values
except TypeError:
# BAR has already been replaced
pass
setattr(namespace, 'bar', defaultbar)
parser = argparse.ArgumentParser()
parser.add_argument("--foo", required=True, action=FooAction)
parser.add_argument("--bar", default="%s_BAR")
args = parser.parse_args(['--foo', 'Foo', '--bar', 'Bar'])
# Namespace(bar='Bar', foo='Foo')
args = parser.parse_args(['--foo', 'Foo'])
# Namespace(bar='Foo_BAR', foo='Foo')
args = parser.parse_args(['--bar', 'Bar', '--foo', 'Foo'])
# Namespace(bar='Bar', foo='Foo')
请注意,该类必须知道dest
参数的--bar
。我还使用'%s_BAR'
来轻松区分默认值和非默认值。这样可以处理--bar
之前出现--foo
的情况。
使这种方法复杂化的是:
add_argument
。parse_args
开头的命名空间中。Action
类不是为处理交互式参数而设计的。bar
操作。bar
默认值可能是一个函数,但必须在parse_args
之后检查是否需要进行评估。虽然这个自定义Action可以解决这个问题,但我仍然认为我的另一个答案中的addbar
函数是一个更清晰的解决方案。