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

问题:如何读取/处理命令行参数?

我原本是C程序员。我看到了许多花招和“技巧”来阅读许多不同的论点。

Python程序员可以通过哪些方式做到这一点?

有关


回答 0

标准库中的规范解决方案是argparsedocs):

这是一个例子:

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 支持(除其他外):

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

The canonical solution in the standard library is argparse (docs):

Here is an example:

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 supports (among other things):

  • Multiple options in any order.
  • Short and long options.
  • Default values.
  • Generation of a usage help message.

回答 1

import sys

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

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

基本上,

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

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

sys.argv is a list that contains all the arguments passed to the script on the command line.

Basically,

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

回答 2

出于这些原因,只是为了使argparse传福音就更好了..本质上:

(从链接复制)

  • argparse模块可以处理位置和可选参数,而optparse仅可以处理可选参数

  • argparse对您的命令行界面应该是什么样的并不教条-支持-file或/ file之类的选项,以及必需的选项。Optparse拒绝支持这些功能,而是偏向于纯度而不是实用性

  • argparse会生成更多有用的用法消息,包括根据您的参数确定的命令行用法,以及有关位置参数和可选参数的帮助消息。optparse模块需要您编写自己的用法字符串,并且无法显示位置参数的帮助。

  • argparse支持消耗可变数量的命令行args的操作,而optparse要求事先知道确切数量的参数(例如1、2或3)

  • argparse支持分派到子命令allow_interspersed_args的解析器,而optparse需要手动设置 和执行解析器分派

和我个人最喜欢的:

  • argparse允许add_argument() 使用简单的可调用对象来指定类型和操作参数,而optparse则需要侵入类属性,例如 STORE_ACTIONSCHECK_METHODS进行正确的参数检查。

Just going around evangelizing for argparse which is better for these reasons.. essentially:

(copied from the link)

  • argparse module can handle positional and optional arguments, while optparse can handle only optional arguments

  • argparse isn’t dogmatic about what your command line interface should look like – options like -file or /file are supported, as are required options. Optparse refuses to support these features, preferring purity over practicality

  • argparse produces more informative usage messages, including command-line usage determined from your arguments, and help messages for both positional and optional arguments. The optparse module requires you to write your own usage string, and has no way to display help for positional arguments.

  • argparse supports action that consume a variable number of command-line args, while optparse requires that the exact number of arguments (e.g. 1, 2, or 3) be known in advance

  • argparse supports parsers that dispatch to sub-commands, while optparse requires setting allow_interspersed_args and doing the parser dispatch manually

And my personal favorite:

  • argparse allows the type and action parameters to add_argument() to be specified with simple callables, while optparse requires hacking class attributes like STORE_ACTIONS or CHECK_METHODS to get proper argument checking

回答 3

还有argparsestdlib模块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

There is also argparse stdlib module (an “impovement” on stdlib’s optparse module). Example from the introduction to 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))

Usage:

$ script.py 1 2 3 4
4

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

回答 4

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

import sys

for arg in sys.argv:
    print arg

One way to do it is using sys.argv. This will print the script name as the first argument and all the other parameters that you pass to it.

import sys

for arg in sys.argv:
    print arg

回答 5

docopt库是真的光滑。它从应用程序的用法字符串中构建一个参数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)

The docopt library is really slick. It builds an argument dict from the usage string for your app.

Eg from the docopt readme:

"""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)

回答 6

如果您需要快速但不太灵活的东西

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

产生以下输出:

你好詹姆斯史密斯

If you need something fast and not very flexible

main.py:

import sys

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

Then run python main.py James Smith

to produce the following output:

Hello James Smith


回答 7

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

回答 8

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

“对函数定义(包括其参数及其默认值)进行自省,并使用其来构建命令行参数解析器。”

因此,例如,此函数定义:

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

变成以下optparse帮助文本:

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

I use optparse myself, but really like the direction Simon Willison is taking with his recently introduced optfunc library. It works by:

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

So, for example, this function definition:

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

is turned into this optparse help text:

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

回答 9

我喜欢stdlib中的getopt,例如:

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”隐式)。

I like getopt from stdlib, eg:

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...")

Lately I have been wrapping something similiar to this to make things less verbose (eg; making “-h” implicit).


回答 10

Pocoo的点击更加直观,所需模板更少,并且至少与argparse一样强大。

到目前为止,我遇到的唯一弱点是您不能做太多自定义来帮助页面,但这通常不是必需的,docopt似乎是明确的选择。

Pocoo’s click is more intuitive, requires less boilerplate, and is at least as powerful as argparse.

The only weakness I’ve encountered so far is that you can’t do much customization to help pages, but that usually isn’t a requirement and docopt seems like the clear choice when it is.


回答 11

如您所见,optparse “ optparse模块已弃用,将不再进一步开发;argparse模块将继续开发。”

As you can see optparse “The optparse module is deprecated with and will not be developed further; development will continue with the argparse module.”


回答 12

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
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

回答 13

您可能对我编写的一个Python小模块感兴趣,该模块使命令行参数的处理更加容易(开源且免费使用)-Commando

You may be interested in a little Python module I wrote to make handling of command line arguments even easier (open source and free to use) – Commando


回答 14

我建议将docopt看作是其他替代品的简单替代方案。

docopt是一个新项目,可以通过解析–help使用情况消息来工作,而不是要求您自己实现一切。您只需要将使用情况消息以POSIX格式输入即可。

I recommend looking at docopt as a simple alternative to these others.

docopt is a new project that works by parsing your –help usage message rather than requiring you to implement everything yourself. You just have to put your usage message in the POSIX format.


回答 15

另一个选择是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()

它会自动生成帮助,等等,您可以使用装饰器提供有关arg解析工作方式的额外指导。

Yet another option is argh. It builds on argparse, and lets you write things like:

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()

It will automatically generate help and so on, and you can use decorators to provide extra guidance on how the arg-parsing should work.


回答 16

我的解决方案是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

My solution is entrypoint2. Example:

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

help text:

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