Argparse:检查是否已传递任何参数

时间:2012-05-22 08:33:35

标签: python command-line-arguments argparse

当没有给出参数时,我的脚本应该启动演示模式。我试过这个:

args = parser.parse_args()
if len(args) == 0:
    run_demo()
else:
    # evaluate args

哪个*** TypeError: object of type 'Namespace' has no len()args是没有列表的。

我如何实现我的目标?

8 个答案:

答案 0 :(得分:65)

如果您的目标是检测何时没有参数,那么通过argparse执行此操作是错误的方法(正如Ben已经指出的那样)。

想想简单! :-)我相信argparse不会减少sys.argv。所以,if not len(sys.argv) > 1,然后用户没有提供任何参数。

答案 1 :(得分:16)

argparse允许您根据规范和要解析的命令行设置(在Namespace对象内)您添加到解析器的参数中提到的所有变量。如果设置了默认值,那么这些变量将具有该默认值(如果在命令行中未显示它们),它们将不会在Namespace对象中不存在。如果您指定默认值,则隐式默认值为None。因此,检查Namespace对象的长度,但是你设法做到这一点,作为检查是否解析了任何参数的方法没有意义;它应始终具有相同的长度。

相反,如果你知道你有一堆没有默认值的参数,你想检查它们中的任何一个是否被设置为任何非None值......那样做。您可以使用列表推导和vars函数来循环它们,而不必复制add_argument调用中的名称列表,如Martijn的回答所示。

如果你的一些参数有默认值,它会变得有点棘手,如果它们具有可以在命令行中显式提供的默认值,那就更难了(例如,默认为0的数字参数使得无法告知默认值来自提供0)的用户。在那种情况下,我不确定是否有一个通用的解决方案总能在不知道参数是什么的情况下工作。

答案 2 :(得分:6)

如果真的需要参数号(无论出于何种原因)。 我发现这段代码非常有用(但不知道它有多少优化,我很感激任何评论)。

args = parser.parse_args()
print( len( vars(args) ) )

此版本仅计算-xx参数,而不计算任何其他附加值。

如果想要所有内容(也是传递的值),那么只需使用前面提到的len(sys.argv)

答案 3 :(得分:5)

不要使用argparse。而只是使用sys.argvargparse创建一个命名空间,因此它总是会为您提供一个带有值的“dict”,具体取决于您在调用脚本时使用的参数。

以下是我过去所做的事情:

args = parser.parse_args()
if len(sys.argv) == 1:
    parser.print_help()
    sys.exit()
return args

答案 4 :(得分:2)

让我们假设以下示例扩展您的完整性:

#!/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.inputargs.lengthargs.verbose访问它。您可以通过执行print(args)来验证这一点,Namespace(input=None, length=None, verbose=False) 实际上会显示如下内容:

True

因为verbose设置为group = parser.add_mutually_exclusive_group(),如果存在,输入和长度只是变量,不必实例化(不提供参数)。

如果您想确保,string token = user.SignonInfo.SessToken;也很有用,则无法同时提供两个属性。

如需进一步参考,请参阅:

答案 5 :(得分:1)

我扩展了2dvisio的概念来计算非零或无参数:

vm_opts = parser.parse_args()
v = vars(vm_opts)
n_args = sum([ 1 for a in v.values( ) if a])

答案 6 :(得分:1)

我知道这是一个旧线程,但是我发现了一种更直接的解决方案,该解决方案也可能对其他人有用:

您可以检查是否传递了任何参数:

if any(vars(args).values()):
    # your code here

或者,如果未传递任何参数(请注意not运算符):

if not any(vars(args).values()):
    # your code here

说明:

  • parse_args()返回包含每个参数名称及其关联值的“名称空间”对象。 示例:Namespace(arg1='myfile.txt', arg2='some/path/to/some/folder')

  • 如果未传递任何参数,则parse_args()将返回相同的对象,但所有值均为None。 示例:Namespace(arg1=None, arg2=None)

不过,该对象不是可迭代的,因此您必须使用vars()将其转换为dict,以便我们可以访问值。

最后,由于我们现在手头有一个dict,因此我们可以使用list获取所有值(在.values()中),并使用内置的{{1 }}函数来检查是否有任何值不是any()。 更清楚地说:如果没有一个不是Noneany()False的值,None将返回False(请查阅文档以供参考) )添加到列表中。

希望有帮助。

答案 7 :(得分:0)

对于最简单的情况,您要检查是否传递了所有输入中相同的单一类型的参数,您可以使用 argparsenumpy 分三步完成。

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")

长度用作代理来检查是否已传递anyno 参数。如果您想知道通过了哪一个,您可以打开密钥并检查更改后的索引。

np.array() 接受用于更复杂情况的逻辑运算符。