如何读取和处理命令行参数?

799

6
使用 docopt(参见 @ralbatross 在 https://dev59.com/hXNA5IYBdhLWcg3wVcFx#14790373 中的回答)。我已经尝试了其他所有方法,但实际上 docopt 是我今后唯一会使用的方法。 - Pat
3
我认为没有一种单一的最佳方法。argparse是标准且功能丰富的。docopt非常优雅,但不在标准库中。对于非常简单的轻量级使用,您可以使函数默认值处理命令行参数默认值 - Simon Hibbs
22个回答

9
Pocoo的click比argparse更直观,需要的样板文件更少,至少同样强大。
到目前为止,我遇到的唯一弱点是无法对帮助页面进行很多自定义,但那通常不是必需的,当需要时docopt似乎是明显的选择。

8

如您所见,optparse模块已被弃用,并且不会再进行开发;而argparse模块将继续进行开发。


6
import argparse

parser = argparse.ArgumentParser(description='Process some integers.')
parser.add_argument('integers', metavar='N', type=int, nargs='+',
                   help='an integer for the accumulator')
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))

Assuming the Python code above is saved into a file called prog.py
$ python prog.py -h

Ref-link: https://docs.python.org/3.3/library/argparse.html

5

另一个选择是argh。它基于argparse,并允许您编写类似以下的内容:

import argh

# declaring:

def echo(text):
    "Returns given word as is."
    return text

def greet(name, greeting='Hello'):
    "Greets the user with given name. The greeting is customizable."
    return greeting + ', ' + name

# assembling:

parser = argh.ArghParser()
parser.add_commands([echo, greet])

# dispatching:

if __name__ == '__main__':
    parser.dispatch()

它会自动生成帮助等内容,并且您可以使用装饰器来提供有关参数解析应如何工作的额外指导。


1
这是最佳解决方案。使用 argh 比其他库或使用 sys 更容易。 - Juanjo Salvador
1
我本想喜欢 argh,但它并不特别适用于那些最希望没有子命令的场景。 - tripleee
2
@tripleee YMMV,但我发现这更多是文档中的缺陷而不是库本身的问题。似乎完全可以有def frobnicate_spleches(...)定义一个执行脚本所需操作的函数,然后在文件末尾执行if __name__ == '__main__': argh.dispatch_command(frobnicate_spleches) - circular-ruin

5

我写了一个小的Python模块,可以更轻松地处理命令行参数(开源且免费使用)- Commando


2
已经有另一个命令行解析模块叫做Commando:https://github.com/lakshmivyas/commando。它通过使用装饰器来封装argparse。 - Roberto Bonvallet
2
Python和轮子的重新发明 - Derek

4
我建议查看docopt作为这些其他选项的简单替代方案。
Docopt是一个新项目,它通过解析您的--help使用消息来工作,而不需要您自己实现所有内容。您只需将使用消息放入POSIX格式中即可。

3

新答案的原因:

  1. 现有答案指定了多个选项。
  2. 标准选项是使用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 关键字来指定参数的预期类型。

    parser.add_argument("age", type=int, help="这个人的年龄")

  • 你可以使用 default 关键字来指定参数的默认值。

这个文件将帮助你在一定程度上理解它。


3

使用Python 3时,您可能会发现方便使用扩展可迭代拆包来处理可选的位置参数而不需要额外的依赖:

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解包使arg2arg3“可选” - 如果它们没有在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)

1
import sys

# Command line arguments are stored into sys.argv
# print(sys.argv[1:])

# I used the slice [1:] to print all the elements except the first
# This because the first element of sys.argv is the program name
# So the first argument is sys.argv[1], the second is sys.argv[2] ecc

print("File name: " + sys.argv[0])
print("Arguments:")
for i in sys.argv[1:]:
    print(i)

让我们把这个文件命名为command_line.py,然后运行它:

C:\Users\simone> python command_line.py arg1 arg2 arg3 ecc
File name: command_line.py
Arguments:
arg1
arg2
arg3
ecc

现在让我们编写一个简单的程序,sum.py:

import sys

try:
    print(sum(map(float, sys.argv[1:])))
except:
    print("An error has occurred")

结果:

C:\Users\simone> python sum.py 10 4 6 3
23

0

我的解决方案是entrypoint2。例如:

from entrypoint2 import entrypoint
@entrypoint
def add(file, quiet=True): 
    ''' This function writes report.

    :param file: write report to FILE
    :param quiet: don't print status messages to stdout
    '''
    print file,quiet

帮助文本:

usage: report.py [-h] [-q] [--debug] file

This function writes report.

positional arguments:
  file         write report to FILE

optional arguments:
  -h, --help   show this help message and exit
  -q, --quiet  don't print status messages to stdout
  --debug      set logging level to DEBUG

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接