关于python:如何读取/处理命令行参数?

How to read/process command line arguments?

我最初是C程序员。我看到过许多技巧和"黑客"阅读许多不同的论点。

Python程序员可以用什么方法做到这一点?

相关的

  • 获取/解析传递给Python脚本的命令行参数的最佳方法是什么?
  • 实现"[命令][操作][参数]"样式的命令行接口?
  • 如何在python中处理命令行参数?
  • 如何格式化位置参数有助于使用Python的optparse?


1
2
3
4
import sys

print("
"
.join(sys.argv))

sys.argv是一个包含在命令行上传递给脚本的所有参数的列表。

基本上,

1
2
import sys
print(sys.argv[1:])


标准库中的规范解是argparse(docs):

下面是一个例子:

1
2
3
4
5
6
7
8
9
10
from argparse import ArgumentParser

parser = ArgumentParser()
parser.add_argument("-f","--file", dest="filename",
                    help="write report to FILE", metavar="FILE")
parser.add_argument("-q","--quiet",
                    action="store_false", dest="verbose", default=True,
                    help="don't print status messages to stdout")

args = parser.parse_args()

argparse支持(除其他外):

  • 任意顺序的多个选项。
  • 长短期权。
  • 默认值。
  • 生成使用帮助消息。


只是到处宣扬argparse,这是因为这些原因更好。基本上:

(从链接复制)

  • argparse模块可以处理位置和可选参数,而optparse只能处理可选的争论

  • argparse并不武断你的命令行界面应该像-选项像-文件支持或/文件,如必需选项。optparse拒绝支持这些功能,首选纯粹多于实用

  • argparse产生更多信息性使用信息,包括命令行用法由确定您的参数和帮助消息位置和可选争论。optparse模块要求您编写自己的用法字符串,无法显示位置参数帮助。

  • argparse支持的操作消耗可变数量的命令行参数,而optparse要求已知参数(例如1、2或3)提前

  • argparse支持调度到子命令,同时optparse需要设置allow_interspersed_args和做解析器手动调度

我个人最喜欢的是:

  • argparse允许类型和add_argument()动作参数用简单的可调用,而optparse需要黑客类属性STORE_ACTIONSCHECK_METHODS得到正确的论证检查


还有argparsestdlib模块(stdlib的optparse模块上的一个"扣押")。argparse简介中的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 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))

用途:

1
2
3
4
5
$ script.py 1 2 3 4
4

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


一种方法是使用sys.argv。这将把脚本名打印为第一个参数以及传递给它的所有其他参数。

1
2
3
4
import sys

for arg in sys.argv:
    print arg

Docopt库真的很光滑。它根据应用程序的使用字符串构建一个参数dict。

例如,从docopt自述文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
"""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)


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

MY.PY:

1
2
3
4
5
import sys

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

然后运行python main.py James Smith

要产生以下输出:

Hello James Smith


1
2
#set default args as -h , if no args:
if len(sys.argv) == 1: sys.argv[1:] = ["-h"]

我自己使用optparse,但我很喜欢Simon Willison最近引进的optfunc库的发展方向。它的工作原理是:

"introspecting a function
definition (including its arguments
and their default values) and using
that to construct a command line
argument parser."

例如,这个函数定义:

1
def geocode(s, api_key='', geocoder='google', list_geocoders=False):

已转换为此optparse帮助文本:

1
2
3
4
5
    Options:
      -h, --help            show this help message and exit
      -l, --list-geocoders
      -a API_KEY, --api-key=API_KEY
      -g GEOCODER, --geocoder=GEOCODER

我喜欢来自stdlib的getopt,例如:

1
2
3
4
5
6
7
8
9
10
11
try:
    opts, args = getopt.getopt(sys.argv[1:], 'h', ['help'])
except getopt.GetoptError, err:
    usage(err)

for opt, arg in opts:
    if opt in ('-h', '--help'):
        usage()

if len(args) != 1:
    usage("specify thing...")

最近,我一直在包装类似的东西,使事情不那么冗长(例如,使"-h"隐式)。


如您所见,optparse"optparse模块已弃用,不会进一步开发;开发将继续使用argparse模块。"


Pocoo的点击更直观,所需的样板文件更少,并且至少和argparse一样强大。

到目前为止,我遇到的唯一弱点是,您不能对帮助页面进行太多的定制,但这通常不是一项要求,docopt似乎是一个明确的选择。


您可能会对我编写的一个小python模块感兴趣,它可以使命令行参数的处理更加容易(开源和免费使用)——commando


我建议将docopt视为这些其他选项的简单替代方案。

docopt是一个新的项目,它通过解析--help用法消息而不是要求您自己实现所有内容来工作。您只需将您的使用消息设置为POSIX格式。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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

另一个选择是argh。它以argparse为基础,允许您编写以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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()

它将自动生成帮助等,并且您可以使用修饰符提供关于arg解析应该如何工作的额外指导。


我的解决方案是入口点2。例子:

1
2
3
4
5
6
7
8
9
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

帮助文本:

1
2
3
4
5
6
7
8
9
10
11
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