检查是否定义了sys.argv [x]

问题:检查是否定义了sys.argv [x]

检查脚本是否传递变量的最佳方法是什么:

try:
    sys.argv[1]
except NameError:
    startingpoint = 'blah'
else:
    startingpoint = sys.argv[1]

What would be the best way to check if a variable was passed along for the script:

try:
    sys.argv[1]
except NameError:
    startingpoint = 'blah'
else:
    startingpoint = sys.argv[1]

回答 0

最后,try, except测试与测试之间的差异len(sys.argv)并不是很大。与argparse。相比,他们都有点笨拙。

不过,这对我来说是一种低成本的argparse:

arg_names = ['command', 'x', 'y', 'operation', 'option']
args = dict(zip(arg_names, sys.argv))

您甚至可以使用它生成namedtuple默认值为None-的四行内容的!

Arg_list = collections.namedtuple('Arg_list', arg_names)
args = Arg_list(*(args.get(arg, None) for arg in arg_names))

如果您不熟悉namedtuple,它只是一个像对象一样的元组,允许您使用tup.attribute语法而不是tup[0]语法访问其值。

因此,第一行将namedtuple为中的每个值创建一个新类型arg_names。第二行传递args字典中的get值,当给定的参数名称在字典中没有关联的值时,用于返回默认值。

In the end, the difference between try, except and testing len(sys.argv) isn’t all that significant. They’re both a bit hackish compared to argparse.

This occurs to me, though — as a sort of low-budget argparse:

arg_names = ['command', 'x', 'y', 'operation', 'option']
args = dict(zip(arg_names, sys.argv))

You could even use it to generate a namedtuple with values that default to None — all in four lines!

Arg_list = collections.namedtuple('Arg_list', arg_names)
args = Arg_list(*(args.get(arg, None) for arg in arg_names))

In case you’re not familiar with namedtuple, it’s just a tuple that acts like an object, allowing you to access its values using tup.attribute syntax instead of tup[0] syntax.

So the first line creates a new namedtuple type with values for each of the values in arg_names. The second line passes the values from the args dictionary, using get to return a default value when the given argument name doesn’t have an associated value in the dictionary.


回答 1

检查的长度sys.argv

if len(sys.argv) > 1:
    blah = sys.argv[1]
else:
    blah = 'blah'

有些人喜欢您建议的基于异常的方法(例如try: blah = sys.argv[1]; except IndexError: blah = 'blah'),但我不太喜欢它,因为它不能很好地“扩展”(例如,当您要接受两个或三个参数时)并可能隐藏错误(例如,如果您使用blah = foo(sys.argv[1]),但foo(...)引发IndexErrorIndexError将被忽略)。

Check the length of sys.argv:

if len(sys.argv) > 1:
    blah = sys.argv[1]
else:
    blah = 'blah'

Some people prefer the exception-based approach you’ve suggested (eg, try: blah = sys.argv[1]; except IndexError: blah = 'blah'), but I don’t like it as much because it doesn’t “scale” nearly as nicely (eg, when you want to accept two or three arguments) and it can potentially hide errors (eg, if you used blah = foo(sys.argv[1]), but foo(...) raised an IndexError, that IndexError would be ignored).


回答 2

我尚未看到的另一种方式是提前设置您的哨兵值。该方法利用了Python的惰性评估,在这种评估中,您不必总是提供一条else语句。例:

startingpoint = 'blah'
if len(sys.argv) >= 2:
  startingpoint = sys.argv[1]

或者,如果您要使用CRAZY语法,则可以使用Python的三元运算符

startingpoint = sys.argv[1] if len(sys.argv) >= 2 else 'blah'

Another way I haven’t seen listed yet is to set your sentinel value ahead of time. This method takes advantage of Python’s lazy evaluation, in which you don’t always have to provide an else statement. Example:

startingpoint = 'blah'
if len(sys.argv) >= 2:
  startingpoint = sys.argv[1]

Or if you’re going syntax CRAZY you could use Python’s ternary operator:

startingpoint = sys.argv[1] if len(sys.argv) >= 2 else 'blah'

回答 3

我用它-它永远不会失败:

startingpoint = 'blah'
if sys.argv[1:]:
   startingpoint = sys.argv[1]

I use this – it never fails:

startingpoint = 'blah'
if sys.argv[1:]:
   startingpoint = sys.argv[1]

回答 4

这是一个普通的Python列表。您可能会捕获到的异常是IndexError,但最好还是检查一下长度。

if len(sys.argv) >= 2:
  startingpoint = sys.argv[1]
else:
  startingpoint = 'blah'

It’s an ordinary Python list. The exception that you would catch for this is IndexError, but you’re better off just checking the length instead.

if len(sys.argv) >= 2:
  startingpoint = sys.argv[1]
else:
  startingpoint = 'blah'

回答 5

使用地图内置功能的解决方案!

arg_names = ['command' ,'operation', 'parameter']
args = map(None, arg_names, sys.argv)
args = {k:v for (k,v) in args}

然后,您只需要像这样调用参数即可:

if args['operation'] == "division":
    if not args['parameter']:
        ...
    if args['parameter'] == "euclidian":
        ...

A solution working with map built-in fonction !

arg_names = ['command' ,'operation', 'parameter']
args = map(None, arg_names, sys.argv)
args = {k:v for (k,v) in args}

Then you just have to call your parameters like this:

if args['operation'] == "division":
    if not args['parameter']:
        ...
    if args['parameter'] == "euclidian":
        ...

回答 6

您可以简单地将argv [1]的值附加到argv,然后检查argv [1]是否不等于您输入的字符串。示​​例:

from sys import argv
argv.append('SomeString')
if argv[1]!="SomeString":
            print(argv[1])

You can simply append the value of argv[1] to argv and then check if argv[1] doesn’t equal the string you inputted Example:

from sys import argv
argv.append('SomeString')
if argv[1]!="SomeString":
            print(argv[1])

回答 7

与发起者试图做的非常接近。这是我使用的功能:

def get_arg(index):
    try:
        sys.argv[index]
    except IndexError:
        return ''
    else:
        return sys.argv[index]

因此用法如下:

if __name__ == "__main__":
    banner(get_arg(1),get_arg(2))

Pretty close to what the originator was trying to do. Here is a function I use:

def get_arg(index):
    try:
        sys.argv[index]
    except IndexError:
        return ''
    else:
        return sys.argv[index]

So a usage would be something like:

if __name__ == "__main__":
    banner(get_arg(1),get_arg(2))