我正在使用Python 3 argparse获取命令行参数。我有一个带有默认值的可选参数。当我读取其值时,是否可以知道用户是手动输入该值还是默认值?
之前,我的设计如上所述。现在,我想存储以前使用的首选项。因此,如果用户未向可选参数输入任何值,那么我想从以前的用法(如果有)中获取该值。因此,我想确定该值是默认值还是用户给定值。
编辑1 :我有多个这样的参数。我知道我可以删除参数的默认值,并在以后以编程方式分配它们。我只想知道是否有一个更简单的解决方案
答案 0 :(得分:3)
如果用户没有向可选参数输入任何值,那么我想从以前的用法中获取值(如果有)。因此,我想确定该值是默认值还是用户给定值。
然后,您不想提供默认值;将参数设置为可选参数(例如Argparse optional positional arguments?),然后显式检查结果名称空间对象中是否存在该参数,并在代码逻辑中进行适当的操作-大概检查先前用法和中的值然后提供默认值作为最后的选择。 (将默认值视为处理缺少该值的捷径逻辑;您需要更复杂的逻辑,因此与尝试解决该问题相比,最好替换该系统。)
答案 1 :(得分:1)
确定用户是否提供值的最可靠方法是将默认值保留为默认值None
。用户无法说会产生相同的结果。然后,在解析之后,您需要做的就是:
if args.myval is None:
# no user input, set my own special default
else:
# user value
如果设置default=argparse.SUPPRESS
,则args
命名空间中的属性将被省略。但是对这种情况进行测试会比较尴尬。
args.myval
将引发错误,您可能会发现该错误。或者,您可以使用hasattr(args, 'myval'). Or handle the missing key in
vars(args)`。
内部parse_args
维护(实际上是set
个动作)列表。这用于测试所需的操作。但这对用户不可用。如果可以的话,老练的用户可以执行更多种共现测试。
In [28]: import argparse
In [29]: parser = argparse.ArgumentParser()
In [30]: a1 = parser.add_argument('-f','--foo')
没有值的测试:
In [31]: args = parser.parse_args([])
In [32]: args
Out[32]: Namespace(foo=None) # foo is present
In [33]: args.foo is None
Out[33]: True
将默认值更改为SUPPRESS
:
In [35]: a1.default = argparse.SUPPRESS
In [36]: args = parser.parse_args([])
In [37]: args
Out[37]: Namespace() # foo is missing
In [38]: args.foo
AttributeError: 'Namespace' object has no attribute 'foo'
我们可以将args.foo
放在try: except AttributeError
块中。
In [39]: hasattr(args, 'foo')
Out[39]: False
或字典测试缺失值
In [46]: vars(args)
Out[46]: {}
In [47]: vars(args).get('foo') is None
Out[47]: True
In [48]: 'foo' in vars(args)
Out[48]: False
默认值提供有效的有用值时最有用,并且可以避免解析后进行额外的测试。