argparse默认选项基于另一个选项

par*_*yzm 16 default argparse

假设我有一个argparse python脚本:

import argparse
parser = argparse.ArgumentParser()

parser.add_argument("--foo", required=True)
Run Code Online (Sandbox Code Playgroud)

现在我想添加另一个选项--bar,它默认将"_BAR"附加到--foo参数指定的任何内容.

我的目标:

>>> parser.parse_args(['--foo', 'FOO'])
>>> Namespace(foo='FOO', bar="FOO_BAR")
Run Code Online (Sandbox Code Playgroud)

>>> parser.parse_args(['--foo', 'FOO', '--bar', 'BAR'])
>>> Namespace(foo='FOO', bar="BAR")
Run Code Online (Sandbox Code Playgroud)

我需要这样的东西:

parser.add_argument("--bar", default=get_optional_foo + "_BAR")
Run Code Online (Sandbox Code Playgroud)

hpa*_*ulj 16

作为第一次尝试,我会使用after-argparse函数来实现这一点.

def addbar(args):
    if args.bar is None:
        args.bar = args.foo+'_BAR'
Run Code Online (Sandbox Code Playgroud)

如果需要将此操作反映在其中help,请自行将其置于此处.

从理论上讲,你可以编写一个自定义Action,foo也可以设置值的bar值.但这需要更多熟悉Action课程.

我尝试了自定义的Action是调整的default的的bar作用,但是这是非常棘手. parse_args在对任何参数执行操作之前,在开始时使用默认值.


hpa*_*ulj 7

这是编写自定义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')
Run Code Online (Sandbox Code Playgroud)

请注意,类必须知道dest的的--bar说法。另外,我使用a '%s_BAR'可以轻松地区分默认值和非默认值。这可以处理--bar出现在之前的情况--foo

使这种方法复杂化的是:

  • 默认值将在add_argument时间评估。
  • 默认值放在的开头parse_args
  • 标记的(可选)参数可以按任何顺序出现
  • Action班是不是设计来处理交互参数。
  • bar在默认情况下,不会调用该操作。
  • bar默认情况下可能是一个功能,但一些本来后检查parse_args是否需要进行评估与否。

尽管此自定义Action可以解决问题,但我仍然认为addbar其他答案中的功能是一种更干净的解决方案。