解析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而不是getopt。它非常具有声明性:您告诉它选项的名称和它们应该具有的效果(例如,设置一个布尔字段),它会返回给您一个根据您的规范填充的字典。
http://docs.python.org/lib/module-optparse.html
Argparse是正确的方法。下面是如何使用它的简短总结:
1)初始化
import argparse
# Instantiate the parser
parser = argparse.ArgumentParser(description='Optional app description')
2)添加论据
# Required positional argument
parser.add_argument('pos_arg', type=int,
help='A required integer positional argument')
# Optional positional argument
parser.add_argument('opt_pos_arg', type=int, nargs='?',
help='An optional integer positional argument')
# Optional argument
parser.add_argument('--opt_arg', type=int,
help='An optional integer argument')
# Switch
parser.add_argument('--switch', action='store_true',
help='A boolean switch')
3)解析
args = parser.parse_args()
4)访问
print("Argument values:")
print(args.pos_arg)
print(args.opt_pos_arg)
print(args.opt_arg)
print(args.switch)
5)检查价值
if args.pos_arg > 10:
parser.error("pos_arg cannot be larger than 10")
使用
正确使用方法:
$ ./app 1 2 --opt_arg 3 --switch
Argument values:
1
2
3
True
不正确的参数:
$ ./app foo 2 --opt_arg 3 --switch
usage: convert [-h] [--opt_arg OPT_ARG] [--switch] pos_arg [opt_pos_arg]
app: error: argument pos_arg: invalid int value: 'foo'
$ ./app 11 2 --opt_arg 3
Argument values:
11
2
3
False
usage: app [-h] [--opt_arg OPT_ARG] [--switch] pos_arg [opt_pos_arg]
convert: error: pos_arg cannot be larger than 10
完整的帮助:
$ ./app -h
usage: app [-h] [--opt_arg OPT_ARG] [--switch] pos_arg [opt_pos_arg]
Optional app description
positional arguments:
pos_arg A required integer positional argument
opt_pos_arg An optional integer positional argument
optional arguments:
-h, --help show this help message and exit
--opt_arg OPT_ARG An optional integer argument
--switch A boolean switch
以防万一,如果你需要在Win32 (2K, XP等)上获取unicode参数,这可能会有所帮助:
from ctypes import *
def wmain(argc, argv):
print argc
for i in argv:
print i
return 0
def startup():
size = c_int()
ptr = windll.shell32.CommandLineToArgvW(windll.kernel32.GetCommandLineW(), byref(size))
ref = c_wchar_p * size.value
raw = ref.from_address(ptr)
args = [arg for arg in raw]
windll.kernel32.LocalFree(ptr)
exit(wmain(len(args), args))
startup()
几乎每个人都在使用getopt
下面是文档的示例代码:
import getopt, sys
def main():
try:
opts, args = getopt.getopt(sys.argv[1:], "ho:v", ["help", "output="])
except getopt.GetoptError:
# print help information and exit:
usage()
sys.exit(2)
output = None
verbose = False
for o, a in opts:
if o == "-v":
verbose = True
if o in ("-h", "--help"):
usage()
sys.exit()
if o in ("-o", "--output"):
output = a
总之,这就是它的工作原理。
你有两种选择。一种是接受辩论的,另一种是接受辩论的 就像开关一样。
sys。argv基本上就是你C语言中的char** argv。就像在C语言中,你跳过第一个元素,也就是你程序的名字,只解析参数:
Getopt。Getopt将根据参数中给出的规则解析它。
这里的"ho:v"描述了短参数:- onletter。:表示-o接受一个参数。
最后["help", "output="]描述长参数(——morethanonletter)。 输出后的=再次表示输出接受一个参数。
结果是一对(选项,参数)的列表
如果一个选项不接受任何参数(比如help), arg部分就是一个空字符串。 然后,您通常希望在此列表上进行循环,并像示例中那样测试选项名称。
我希望这对你有所帮助。
我扩展了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)