您如何设计一个脚本来准备将各种可能数量的参数作为 argv?

How can you design a script that is prepared to take varied possible quantity of arguments as argv?

当您为函数提供一组所需的参数或分配 argv 时,代码会要求您提供正确数量的 args,否则它会继续给出 "expected number of things to unpack from a tuple is wrong" 各种错误。

但我每天都使用脚本,这些脚本在给出参数的具体方式以及命令的类型等方面非常动态

我最终想象用 --help 开关制作脚本,列出所有可能的 argv 和您可以添加的选项,但现在我开始,让我们保持它 very , 有点简单:

我希望以下内容不会引发错误,也不会期望给出参数,而是在它们存在时接受它们:

#!/usr/bin/env python3

from sys import argv

script, verbose_option, user_input = argv

if "verbose" in verbose_option:
    verbose_option = True
else:
    verbose_option = False

x = value
if verbose_option == True:
    print("var x is set to value...")
else:
    pass

if user_input == True: # if true, the var contains any value, correct?
    print(user_input)
else:
    print("user_input not given but, ... no problem!")
    user_input = input("> ") # or maybe it has a default value that can be changed from argv

if verbose_option == True:
    print("Would I really need this conditional on every line I left a verbose explanation on?")
else:
    pass

它必须以某种方式知道 user_input 并不是为了冗长只是因为不存在冗长,所以......也许是一个测试参数元组的 len() 的条件分支和数字,“好吧,那一定是这个而不是那个基于那个数字。或者......是否过于复杂并且有更好的方法?

这是一个不太重要的问题:如果没有比我在示例代码中想象的更好的方法,那么冗长的选项必须使代码变得多么混乱,但这是一个额外的问题。尽管能够被视为 argv,但如果未作为 argv 给出,我不想出错并拥有事物的默认值或获取数据的方式。

当然,那里有一些 arg 解析包,但是,如果你想从头开始,你可以尝试类似的东西:

args = sys.argv
if args:
    #Verbose would be a boolean, true if -v in args, false if not
    verbose = '-v' in args
    #Same thing here, making a boolean based on existence
    help = '--help' in args
    #Here we are assuming the arg after '-x' is some variable we want to store
    x = args[args.index('-x') + 1] if '-x' in args else None

对于你的条件,如果 'verbose' 是一个布尔值,你只需要使用:

if verbose:
   do_something

或者您可以这样做:

print('Hello') if verbose else None

您可以这样遍历参数:

def handle_arguments(argv):
    env = {'user_input': []}
    for arg in argv:
        if arg in ['-v', '--verbose']
            env['verbose'] = True
        elif arg in ['-h', '--help']
            display_help()
            sys.exit(0)
        else
            env['user_input'] += [arg]

    if length(env['user_input']) == 0
        env['user_input'] = input('> ')
    else
        env['user_input'].join(' ')

    return env

你有一个接受参数的函数和 returns 一个格式正确的 env 变量。

那么你可以通过移除无用的 sys.argv[0](在此上下文中无用)

将 sys.argv 传递给 handle_arguments
import sys

if __name__ == "__main__":
    env = handle_arguments(sys.argv[1:])
    do_stuff(**env)

其中 stuff 是具有以下原型的函数:

def do_stuff(user_input='', verbose=False):

或者你可以让它接受任何参数:

def do_stuff(**kwargs):

也就是说,它或多或少是参数解析库的基本内部工作。为了使其正确,符合 CLI 用户的期望,您最好使用一个,例如 Click, argparse or my personal favourite docopt.