解析Python命令行参数最简单、最简洁、最灵活的方法或库是什么?
当前回答
使用docopt
自2012年以来,有一个非常简单、强大且非常酷的参数解析模块叫做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)
这就是:2行代码加上你的doc字符串,这是必要的,你可以解析你的参数,并在arguments对象中可用。
使用python-fire
自2017年以来,有另一个很酷的模块叫做蟒火。它可以为您的代码生成一个CLI界面,您可以进行零参数解析。下面是文档中的一个简单示例(这个小程序将函数double暴露给命令行):
import fire
class Calculator(object):
def double(self, number):
return 2 * number
if __name__ == '__main__':
fire.Fire(Calculator)
从命令行,你可以运行:
> calculator.py double 10
20
> calculator.py double --number=15
30
其他回答
我认为大型项目的最佳方法是optparse,但如果您正在寻找一种简单的方法,也许http://werkzeug.pocoo.org/documentation/script适合您。
from werkzeug import script
# actions go here
def action_foo(name=""):
"""action foo does foo"""
pass
def action_bar(id=0, title="default title"):
"""action bar does bar"""
pass
if __name__ == '__main__':
script.run()
所以基本上每个函数action_*都暴露在命令行和一个nice 免费生成帮助信息。
python foo.py
usage: foo.py <action> [<options>]
foo.py --help
actions:
bar:
action bar does bar
--id integer 0
--title string default title
foo:
action foo does foo
--name string
这个答案建议optparse适用于较旧的Python版本。对于Python 2.7及以上版本,argparse替换optparse。更多信息请看这个答案。
正如其他人指出的那样,您最好使用optparse而不是getopt。getopt基本上是标准getopt(3) C库函数的一对一映射,不太容易使用。
Optparse虽然有点冗长,但结构更好,以后更容易扩展。
下面是向解析器添加选项的典型行:
parser.add_option('-q', '--query',
action="store", dest="query",
help="query string", default="spam")
它本身就说明了一切;在处理时,它将接受-q或——query作为选项,将参数存储在一个名为query的属性中,如果您没有指定它,则有一个默认值。它也是自文档化的,因为你在选项中声明了help参数(在使用-h/——help时使用)。
通常你会这样分析你的论点:
options, args = parser.parse_args()
默认情况下,这将解析传递给脚本的标准参数(sys.argv[1:])
选项。Query将被设置为您传递给脚本的值。
只需执行以下操作即可创建解析器
parser = optparse.OptionParser()
这些都是你需要的基本知识。下面是一个完整的Python脚本:
import optparse
parser = optparse.OptionParser()
parser.add_option('-q', '--query',
action="store", dest="query",
help="query string", default="spam")
options, args = parser.parse_args()
print 'Query string:', options.query
5行python代码告诉你基本原理。
将其保存在sample.py中,并使用
python sample.py
有一次
python sample.py --query myquery
除此之外,您会发现optparse非常容易扩展。 在我的一个项目中,我创建了一个命令类,它允许您轻松地在命令树中嵌套子命令。它大量使用optparse将命令链接在一起。我不能用几行话就解释清楚,但是可以在存储库中随意浏览主类,以及使用它的类和选项解析器
我扩展了Erco的方法,允许使用必需的位置参数和可选参数。这些参数应该在-d, -v等参数之前。
位置参数和可选参数可以分别用PosArg(i)和OptArg(i, default)检索。 当找到一个可选参数时,搜索选项的起始位置(例如-i)将向前移动1,以避免导致“意外”致命。
import os,sys
def HelpAndExit():
print("<<your help output goes here>>")
sys.exit(1)
def Fatal(msg):
sys.stderr.write("%s: %s\n" % (os.path.basename(sys.argv[0]), msg))
sys.exit(1)
def NextArg(i):
'''Return the next command line argument (if there is one)'''
if ((i+1) >= len(sys.argv)):
Fatal("'%s' expected an argument" % sys.argv[i])
return(1, sys.argv[i+1])
def PosArg(i):
'''Return positional argument'''
if i >= len(sys.argv):
Fatal("'%s' expected an argument" % sys.argv[i])
return sys.argv[i]
def OptArg(i, default):
'''Return optional argument (if there is one)'''
if i >= len(sys.argv):
Fatal("'%s' expected an argument" % sys.argv[i])
if sys.argv[i][:1] != '-':
return True, sys.argv[i]
else:
return False, default
### MAIN
if __name__=='__main__':
verbose = 0
debug = 0
infile = "infile"
outfile = "outfile"
options_start = 3
# --- Parse two positional parameters ---
n1 = int(PosArg(1))
n2 = int(PosArg(2))
# --- Parse an optional parameters ---
present, a3 = OptArg(3,50)
n3 = int(a3)
options_start += int(present)
# --- Parse rest of command line ---
skip = 0
for i in range(options_start, len(sys.argv)):
if not skip:
if sys.argv[i][:2] == "-d": debug ^= 1
elif sys.argv[i][:2] == "-v": verbose ^= 1
elif sys.argv[i][:2] == "-i": (skip,infile) = NextArg(i)
elif sys.argv[i][:2] == "-o": (skip,outfile) = NextArg(i)
elif sys.argv[i][:2] == "-h": HelpAndExit()
elif sys.argv[i][:1] == "-": Fatal("'%s' unknown argument" % sys.argv[i])
else: Fatal("'%s' unexpected" % sys.argv[i])
else: skip = 0
print("Number 1 = %d" % n1)
print("Number 2 = %d" % n2)
print("Number 3 = %d" % n3)
print("Debug = %d" % debug)
print("verbose = %d" % verbose)
print("infile = %s" % infile)
print("outfile = %s" % outfile)
由于这些原因,新的流行方法是argparse。Argparse > optparse > getopt
更新:从py2.7开始,argparse是标准库的一部分,optparse已弃用。
轻量级命令行参数默认值
尽管argparse很棒,并且是完整文档化的命令行开关和高级特性的正确答案,但是您可以使用函数参数默认值非常简单地处理直接的位置参数。
import sys
def get_args(name='default', first='a', second=2):
return first, int(second)
first, second = get_args(*sys.argv)
print first, second
'name'参数捕获脚本名称,但不使用。测试输出如下所示:
> ./test.py
a 2
> ./test.py A
A 2
> ./test.py A 20
A 20
对于只想要一些默认值的简单脚本,我发现这已经足够了。您可能还希望在返回值中包含一些类型强制,否则命令行值将全部为字符串。
推荐文章
- 证书验证失败:无法获得本地颁发者证书
- 当使用pip3安装包时,“Python中的ssl模块不可用”
- 无法切换Python与pyenv
- Python if not == vs if !=
- 如何从终端/命令行调用VS代码编辑器
- 如何从scikit-learn决策树中提取决策规则?
- 为什么在Mac OS X v10.9 (Mavericks)的终端中apt-get功能不起作用?
- 将旋转的xtick标签与各自的xtick对齐
- 为什么元组可以包含可变项?
- 如何合并字典的字典?
- 在Jar文件中运行类
- 如何创建类属性?
- 不区分大小写的“in”
- 在Python中获取迭代器中的元素个数
- 解析日期字符串并更改格式