如果未给出参数,我的脚本应该启动演示模式。我尝试了这个:
args = parser.parse_args()
if len(args) == 0:
run_demo()
else:
# evaluate args
使用 argparse
模块时,args
对象是一个 Namespace 类型的对象,而不是列表类型,因此无法使用 len() 函数。如果要计算参数数量,可以使用 len(vars(args))
。
那么如何实现我想要的功能呢?
如果未给出参数,我的脚本应该启动演示模式。我尝试了这个:
args = parser.parse_args()
if len(args) == 0:
run_demo()
else:
# evaluate args
使用 argparse
模块时,args
对象是一个 Namespace 类型的对象,而不是列表类型,因此无法使用 len() 函数。如果要计算参数数量,可以使用 len(vars(args))
。
那么如何实现我想要的功能呢?
argparse
实现这一点是错误的方法(正如Ben所指出的那样)。sys.argv
。因此,如果if not len(sys.argv) > 1
,则用户未提供任何参数。None
,这个问题的实际建议要多得多。 - Benargparse让你能够通过定义规范和解析命令行来在Namespace对象中设置所有添加到解析器的参数所提到的变量。如果你设置了默认值,那么这些变量将具有该默认值,如果它们没有出现在命令行中,它们不会缺失在Namespace对象中。如果你没有指定默认值,则有一个隐含的默认值为None
。因此,检查Namespace对象的长度,无论如何管理它,都没有意义,作为一种检查是否解析了任何参数的方法;它应该始终具有相同的长度。
相反,如果你知道你有一堆没有默认值的参数,并且你想检查它们中是否有任何一个被设置为任何非None
值......就这样做。你可以使用列表推导式和vars
函数循环遍历它们,而不必重复add_argument
调用中名称的列表,就像Martijn的答案中展示的那样。
如果你的一些参数有默认值,那么情况就有点棘手了,尤其是当它们具有可以在命令行上明确提供的默认值时(例如,默认为0的数字参数使得无法区分用户提供的0和默认值)。在这种情况下,我不确定是否有一个通常情况下不需要知道参数是什么的解决方案。
我知道这是一个旧的线程,但我找到了一个更直接的解决方案,可能也对其他人有用:
您可以检查是否传递了任何参数:
if any(vars(args).values()):
# evaluate args
或者,如果没有传递参数(注意使用not
运算符):
if not any(vars(args).values()):
run_demo()
解释:
parse_args()
返回一个包含每个参数名称及其相关值的 "Namespace" 对象。
例如: Namespace(arg1='myfile.txt', arg2='some/path/to/some/folder')
如果没有传入参数,parse_args()
将返回相同的对象,但所有值都为 None
。
例如: Namespace(arg1=None, arg2=None)
然而,这个对象不可迭代,所以您必须使用vars()
将其转换为一个dict
,以便我们可以访问这些值。
最后,因为我们现在有了一个dict
,我们可以使用 .values()
获取所有值(作为一个list
),并使用内置的any()
函数来检查是否有任何一个值不为None
。
为了更清楚: 如果您向 any()
提供的列表中没有单个值为None
, False
或 0
(请参见文档),则它将返回False
。
希望对你有所帮助。
None
,因此这不起作用。 - hkhstore_true
和 store_false
类型的参数会隐式设置默认值。store_true
的默认值是 False
,这不会破坏你的测试(尽管它会破坏 any(var is not None for var in vars(args).values())
),但 store_false
的默认值是 True
,这肯定会破坏测试。 - undefined不要使用argparse,而只需使用sys.argv
。 argparse
会创建一个Namespace对象,它将根据您在调用脚本时使用的参数给出一个"dict"(字典)及其值。
以下是我过去所做的:
args = parser.parse_args()
if len(sys.argv) == 1:
parser.print_help()
sys.exit()
return args
args = parser.parse_args()
print( len( vars(args) ) )
这个版本仅计算 -xx 参数,而不包括传递的任何其他值。
如果想要所有东西(包括传递的值),那么只需像之前提到的那样使用 len(sys.argv)
。
#!/usr/bin/env python3
import argparse
...
def main():
parser = argparse.ArgumentParser()
parser.add_argument('input', nargs='?' action='store')
parser.add_argument('-l', '--length', type=int, action='store')
parser.add_argument('-v', '--verbose', action='store_true')
args = parser.parse_args()
if (args.input == None and args.length == None):
parser.print_help()
else:
print(args)
if __name__ == '__main__':
main()
在这个例子中,@Ben提到的Namespace对象是args
。从parser.add_argument
中的字符串创建了一个变量。您可以通过args.input
或args.length
或args.verbose
访问它。您可以执行print(args)
来验证这一点,它实际上将显示类似于此的内容:
Namespace(input=None, length=None, verbose=False)
由于 verbose 设置为 True
,如果存在且输入和长度只是变量,则不必实例化(没有提供参数)。
如果您想确保不同时提供两个属性,group = parser.add_mutually_exclusive_group()
也可以提供帮助。
有关详细信息,请参阅:
vm_opts = parser.parse_args()
v = vars(vm_opts)
n_args = sum([ 1 for a in v.values( ) if a])
对于最简单的情况,您想要检查是否已传递了所有输入中相同的单个参数类型,您可以使用argparse
和numpy
三个步骤来完成。
import argparse
import numpy as np
args = parser.parse_args()
# namespace to dictionary
args_dict = vars(args)
# unpack values from dictionary, pass to array
values = np.array([*args_dict.values()])
# Check if the defaults have changed
args_indices = np.where(values != default)[0]
# Did we pass any arguments?
if len(values) == len(args_indices):
print("No arguments were passed")
长度被用作代理来检查是否传递了任何或没有参数。如果您想知道哪个已传递,您可以解包键并检查更改的索引。
np.array()
接受逻辑运算符以处理更复杂的情况。
defaults = vars(parser.parse_args([]))
来获取一个包含所有默认值的Namespace
。 - Girardi
len(args)
始终会引发 TypeError 错误。 - huon