在Python中,我们如何找到为脚本提供的命令行参数,并处理它们?


有关更具体的示例,请参见实现“[命令][动作][参数]”风格的命令行界面?以及如何使用Python的optparse格式化位置参数帮助?


当前回答

docopt库非常漂亮。它为你的应用程序从usage字符串中构建一个参数dict。

来自docopt自述文件:

"""Naval Fate.

Usage:
  naval_fate.py ship new <name>...
  naval_fate.py ship <name> move <x> <y> [--speed=<kn>]
  naval_fate.py ship shoot <x> <y>
  naval_fate.py mine (set|remove) <x> <y> [--moored | --drifting]
  naval_fate.py (-h | --help)
  naval_fate.py --version

Options:
  -h --help     Show this screen.
  --version     Show version.
  --speed=<kn>  Speed in knots [default: 10].
  --moored      Moored (anchored) mine.
  --drifting    Drifting mine.

"""
from docopt import docopt


if __name__ == '__main__':
    arguments = docopt(__doc__, version='Naval Fate 2.0')
    print(arguments)

其他回答

如果你需要快速而不灵活的东西

main.py:

import sys

first_name = sys.argv[1]
last_name = sys.argv[2]
print("Hello " + first_name + " " + last_name)

然后运行python main.py James Smith

产生以下输出:

你好,詹姆斯·史密斯

还有argparse stdlib模块(对stdlib的optparse模块的“改进”)。示例来自argparse的介绍:

# script.py
import argparse

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument(
        'integers', metavar='int', type=int, choices=range(10),
         nargs='+', help='an integer in the range 0..9')
    parser.add_argument(
        '--sum', dest='accumulate', action='store_const', const=sum,
        default=max, help='sum the integers (default: find the max)')

    args = parser.parse_args()
    print(args.accumulate(args.integers))

用法:

$ script.py 1 2 3 4
4

$ script.py --sum 1 2 3 4
10

它处理简单的开关,带有可选替代标志的值开关。

import sys

# [IN] argv - array of args
# [IN] switch - switch to seek
# [IN] val - expecting value
# [IN] alt - switch alternative
# returns value or True if val not expected
def parse_cmd(argv,switch,val=None,alt=None):
    for idx, x in enumerate(argv):
        if x == switch or x == alt:
            if val:
                if len(argv) > (idx+1):            
                    if not argv[idx+1].startswith('-'):
                        return argv[idx+1]
            else:
                return True

//expecting a value for -i
i = parse_cmd(sys.argv[1:],"-i", True, "--input")

//no value needed for -p
p = parse_cmd(sys.argv[1:],"-p")

新答案的原因:

现有的答案指定了多个选项。 标准选项是使用argparse,一些答案从文档中提供了示例,其中一个答案提出了它的优点。但是所有OP都不能充分/清楚地解释实际问题的答案,至少对新手来说是这样。

argparse的一个例子:

import argparse


def load_config(conf_file):
    pass


if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    //Specifies one argument from the command line
    //You can have any number of arguments like this
    parser.add_argument("conf_file", help="configuration file for the application") 
    args = parser.parse_args()
    config = load_config(args.conf_file)

上面的程序需要一个配置文件作为参数。如果您提供了它,它将愉快地执行。如果没有,它将打印以下内容

usage: test.py [-h] conf_file
test.py: error: the following arguments are required: conf_file

可以指定参数是否为可选参数。 可以使用type key为参数指定预期的类型 解析器。Add_argument("年龄",type=int, help="人的年龄") 可以通过指定default key来指定参数的默认值

本文档将在一定程度上帮助您理解它。

同样在python3中,你可能会发现使用Extended Iterable Unpacking来处理可选的位置参数很方便,没有额外的依赖关系:

try:
   _, arg1, arg2, arg3, *_ = sys.argv + [None] * 2
except ValueError:
   print("Not enough arguments", file=sys.stderr) # unhandled exception traceback is meaningful enough also
   exit(-1)

上面的argv解包使arg2和arg3成为“可选的”——如果在argv中没有指定它们,它们将是None,而如果没有指定第一个,ValueError将被解析:

Traceback (most recent call last):
  File "test.py", line 3, in <module>
    _, arg1, arg2, arg3, *_ = sys.argv + [None] * 2
ValueError: not enough values to unpack (expected at least 4, got 3)