如何确定是否在命令行上实际指定了 argparse 参数?
How to find out if argparse argument has been actually specified on command line?
我正在使用 arparse 使用在命令行上指定的值来更新配置字典。因为我只想更新命令行中明确提到的值的配置中的值。
因此,我尝试通过检查每个操作是否 getattr(args, action.dest) == action.default
或转换后的参数类型是否相等来识别未指定的参数。然后我更新字典中的所有值,这是错误的。
但这当然会失败,如果我在命令行上明确指定一个与我的默认参数相同的参数。是否有可能使用 argparser 识别这些明确提到的参数,或者我有
在 sys.argv?
中手动识别它们
谢谢!
编辑:
为了让我的意图更清楚。我有如下论点:
parser.add_argument('--test', default='meaningful_default')
和类似
的配置
config = { 'test' : 'nondefault_val'}
现在我只想用明确指定的参数更新配置。将 args 属性与默认值进行比较,只要我不指定类似 prog.py --test meaningful_default
的值来再次更新我的配置,而该值恰好也是默认值
parser
在解析时维护一个 seen_actions
set 对象(在 _parse_known_args
方法中)。在解析结束时,它会根据所需的参数(带有 required=True
的参数)检查此集合,并可能会发出错误。一种变体也用于互斥组。
但是这个变量在那个函数之外是不可用的。缺少某种 'hook' 允许您在 parse_args
操作中应用自己的测试,最好的选择是测试默认值。或者你可以看看sys.argv[1:]
.
默认 default
为 None
。这对于此目的来说很好,因为您的用户无法提供此值。也就是说,没有字符串可以转换为 None
(至少在任何正常的 type
方法中都没有)。
parser.add_argument('--foo') # default=None
...
if args.foo is None:
# clearly foo has not been specified.
args.foo = 'the real default'
else:
# foo was specified
pass
如果您更喜欢使用 argparse 并能够指定默认值,则有一个使用两个解析器的简单解决方案。
我。定义您的主要解析器并使用适当的默认值解析您的所有参数:
parser = argparse.ArgumentParser()
parser.add_argument('--test1', default='meaningful_default1')
parser.add_argument('--test2', default='meaningful_default2')
...
args, unparsed = parser.parse_known_args()
二.使用 argument_default=argparse.SUPPRESS
定义辅助解析器以排除未指定的参数。添加来自主解析器的所有参数但没有任何默认值:
aux_parser = argparse.ArgumentParser(argument_default=argparse.SUPPRESS)
for arg in vars(args): aux_parser.add_argument('--'+arg)
cli_args, _ = aux_parser.parse_known_args()
这不是一个非常优雅的解决方案,但与 argparse 及其所有优点配合使用效果很好。
您可以使用自定义操作来判断 arg 值是默认值还是在命令行上设置:
import argparse
class FooAction(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
setattr(namespace, self.dest, values)
setattr(namespace, self.dest+'_nondefault', True)
parser = argparse.ArgumentParser()
parser.add_argument('--test0', default='meaningful_default', action=FooAction)
parser.add_argument('--test1', default='meaningful_default', action=FooAction)
args = parser.parse_args('--test0 2'.split())
if hasattr(args, 'test0_nondefault'):
print('argument test0 set on command line')
else:
print('default value of test0 is used')
if hasattr(args, 'test1_nondefault'):
print('argument test1 set on command line')
else:
print('default value of test1 is used')
您可以使用“const" and "default" to emulate what you want. "nargs”的组合,在这种情况下必须是 '?'
。例如:
args_group.add_argument('--abc',
metavar='',
nargs='?',
action='store',
const='github.com',
default='',
help='blabla [ default: %(const)s ]')
然后abc
的值将根据不同的命令行参数如下。
abc 不在命令行中:
abc =
--abc
:
abc = github.com
--abc whosebug.com
:
abc = whosebug.com
所以你会知道 abc
为空时不会出现在命令行中,例如:
if not args.abc:
# to something
我正在使用 arparse 使用在命令行上指定的值来更新配置字典。因为我只想更新命令行中明确提到的值的配置中的值。
因此,我尝试通过检查每个操作是否 getattr(args, action.dest) == action.default
或转换后的参数类型是否相等来识别未指定的参数。然后我更新字典中的所有值,这是错误的。
但这当然会失败,如果我在命令行上明确指定一个与我的默认参数相同的参数。是否有可能使用 argparser 识别这些明确提到的参数,或者我有 在 sys.argv?
中手动识别它们谢谢!
编辑:
为了让我的意图更清楚。我有如下论点:
parser.add_argument('--test', default='meaningful_default')
和类似
的配置config = { 'test' : 'nondefault_val'}
现在我只想用明确指定的参数更新配置。将 args 属性与默认值进行比较,只要我不指定类似 prog.py --test meaningful_default
的值来再次更新我的配置,而该值恰好也是默认值
parser
在解析时维护一个 seen_actions
set 对象(在 _parse_known_args
方法中)。在解析结束时,它会根据所需的参数(带有 required=True
的参数)检查此集合,并可能会发出错误。一种变体也用于互斥组。
但是这个变量在那个函数之外是不可用的。缺少某种 'hook' 允许您在 parse_args
操作中应用自己的测试,最好的选择是测试默认值。或者你可以看看sys.argv[1:]
.
默认 default
为 None
。这对于此目的来说很好,因为您的用户无法提供此值。也就是说,没有字符串可以转换为 None
(至少在任何正常的 type
方法中都没有)。
parser.add_argument('--foo') # default=None
...
if args.foo is None:
# clearly foo has not been specified.
args.foo = 'the real default'
else:
# foo was specified
pass
如果您更喜欢使用 argparse 并能够指定默认值,则有一个使用两个解析器的简单解决方案。
我。定义您的主要解析器并使用适当的默认值解析您的所有参数:
parser = argparse.ArgumentParser()
parser.add_argument('--test1', default='meaningful_default1')
parser.add_argument('--test2', default='meaningful_default2')
...
args, unparsed = parser.parse_known_args()
二.使用 argument_default=argparse.SUPPRESS
定义辅助解析器以排除未指定的参数。添加来自主解析器的所有参数但没有任何默认值:
aux_parser = argparse.ArgumentParser(argument_default=argparse.SUPPRESS)
for arg in vars(args): aux_parser.add_argument('--'+arg)
cli_args, _ = aux_parser.parse_known_args()
这不是一个非常优雅的解决方案,但与 argparse 及其所有优点配合使用效果很好。
您可以使用自定义操作来判断 arg 值是默认值还是在命令行上设置:
import argparse
class FooAction(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
setattr(namespace, self.dest, values)
setattr(namespace, self.dest+'_nondefault', True)
parser = argparse.ArgumentParser()
parser.add_argument('--test0', default='meaningful_default', action=FooAction)
parser.add_argument('--test1', default='meaningful_default', action=FooAction)
args = parser.parse_args('--test0 2'.split())
if hasattr(args, 'test0_nondefault'):
print('argument test0 set on command line')
else:
print('default value of test0 is used')
if hasattr(args, 'test1_nondefault'):
print('argument test1 set on command line')
else:
print('default value of test1 is used')
您可以使用“const" and "default" to emulate what you want. "nargs”的组合,在这种情况下必须是 '?'
。例如:
args_group.add_argument('--abc',
metavar='',
nargs='?',
action='store',
const='github.com',
default='',
help='blabla [ default: %(const)s ]')
然后abc
的值将根据不同的命令行参数如下。
abc 不在命令行中:
abc =
--abc
:
abc = github.com
--abc whosebug.com
:
abc = whosebug.com
所以你会知道 abc
为空时不会出现在命令行中,例如:
if not args.abc:
# to something