关于python:如何区分默认值和用户给定值?

How to differentiate between default value and user given value?

我正在使用python 3 argparse获取命令行参数。我有一个带有默认值的可选参数。当我读取它的值时,是否可以知道用户是手动输入的值,还是默认值?

早些时候,我设计了如上所述。现在,我要存储以前使用的首选项。因此,如果用户没有向可选参数输入任何值,我想从以前的用法中获取该值(如果有)。所以,我想确定这个值是作为默认值还是作为用户给定值出现的。

编辑1:我有很多这样的参数。我知道我可以删除参数的默认值,稍后以编程方式分配它们。我只想知道有没有一个更简单的解决办法


if a user didn't input any value to the optional argument, I want to take the value from previous usage (if any). So, I want to determine whether the value came as a default value or user given value.

那么,您不希望提供默认值;将参数设置为可选(例如argparse可选位置参数?),然后显式检查其在生成的命名空间对象中的存在或不存在,并在代码逻辑中执行适当的操作-假定,检查以前的用法中的值,然后提供默认值作为最后的手段。(将默认值视为处理缺少值的快捷逻辑;您需要更复杂的逻辑,因此最好替换该系统,而不是尝试绕过它。)


确定用户是否提供了值的最可靠方法是将默认值保留在默认值None。用户说不出什么能产生同样的结果。然后在分析之后,您需要做的就是:

1
2
3
4
if args.myval is None:
    # no user input, set my own special default
else:
    # user value

如果设置default=argparse.SUPPRESS,该属性将从args名称空间中省略。但是测试这种情况会有点尴尬。

1
args.myval

将引发一个错误,您可以捕获它。或者可以使用hasattr(args, 'myval'). Or handle the missing key invars(args)`。

在内部,parse_args维护了一份它"看到"的行动清单(set)。用于测试所需操作。但这对用户不可用。如果它可用,成熟的用户可以执行更广泛的共存测试。

1
2
3
In [28]: import argparse
In [29]: parser = argparse.ArgumentParser()
In [30]: a1 = parser.add_argument('-f','--foo')

无值测试:

1
2
3
4
5
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

1
2
3
4
5
6
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块。

1
2
In [39]: hasattr(args, 'foo')
Out[39]: False

或字典测试缺少的值

1
2
3
4
5
6
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

当默认值提供了一个有效的、有用的值时,它最有用,并且它可以在解析之后避免额外的测试。