How to read/process command line arguments?
我最初是C程序员。我看到过许多技巧和"黑客"阅读许多不同的论点。
Python程序员可以用什么方法做到这一点?
相关的- 获取/解析传递给Python脚本的命令行参数的最佳方法是什么?
- 实现"[命令][操作][参数]"样式的命令行接口?
- 如何在python中处理命令行参数?
- 如何格式化位置参数有助于使用Python的optparse?
1 2 3 4 | import sys print(" ".join(sys.argv)) |
基本上,
1 2 | import sys print(sys.argv[1:]) |
标准库中的规范解是
下面是一个例子:
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模块可以处理位置和可选参数,而optparse只能处理可选的争论
argparse并不武断你的命令行界面应该像-选项像-文件支持或/文件,如必需选项。optparse拒绝支持这些功能,首选纯粹多于实用
argparse产生更多信息性使用信息,包括命令行用法由确定您的参数和帮助消息位置和可选争论。optparse模块要求您编写自己的用法字符串,无法显示位置参数帮助。
argparse支持的操作消耗可变数量的命令行参数,而optparse要求已知参数(例如1、2或3)提前
argparse支持调度到子命令,同时optparse需要设置
allow_interspersed_args 和做解析器手动调度
我个人最喜欢的是:
- argparse允许类型和
add_argument() 动作参数用简单的可调用,而optparse需要黑客类属性STORE_ACTIONS 或CHECK_METHODS 得到正确的论证检查
还有
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 |
一种方法是使用
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) |
然后运行
要产生以下输出:
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 |