抓取/parsing传递给Python脚本的命令行参数的最好方法是什么?

什么是parsingPython命令行参数的最简单,最简单,最灵活的方法或库?

这个答案build议optparse适用于较旧的Python版本。 对于Python 2.7及以上版本, argparsereplaceoptparse 请参阅此答案以获取更多信息。

正如其他人所指出的那样,你最好是通过getopt来进行optparse。 getopt几乎是标准getopt(3)C库函数的一对一映射,并不是很容易使用。

optparse虽然稍微冗长些,但稍后可以更好地进行结构化和简化。

这是一个典型的添加选项的parsing器:

 parser.add_option('-q', '--query', action="store", dest="query", help="query string", default="spam") 

这几乎说明了一切。 在处理时,它将接受-q或–query作为选项,将参数存储在一个名为query的属性中,如果没有指定它,则具有默认值。 它也是自我logging的,因为你在那里用选项声明了帮助参数(在使用-h / – help运行时使用)。

通常你用以下方法parsing你的论点:

 options, args = parser.parse_args() 

这将在默认情况下parsing传递给脚本的标准参数(sys.argv [1:])

options.query将被设置为你传递给脚本的值。

你只要做一个parsing器就可以了

 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非常容易扩展。 在我的一个项目中,我创build了一个Command类,它允许您轻松地在命令树中嵌套子命令。 它大量使用optparse来将命令链接在一起。 这不是我可以简单地用几行解释的东西,而是随意浏览我的资源库中的主类,以及使用它的类和选项parsing器

其他答案也提到, argparse是新Python的一种方式,但不要提供使用示例。 为了完整起见,下面是如何使用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)parsing

 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 

使用docopt

自2012年以来,Python有一个非常简单,function强大且非常酷的模块,用于参数parsing(称为docopt) 。 它适用于Python 2.6到3.5,不需要安装(只需复制它)。 这是一个从它的文档中取得的例子:

 """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行代码加上你的文档string必不可less的,你得到你的参数parsing和可用的参数对象。 我告诉你这很酷,不是我;-)

使用python-fire

自2017年以来, python-fire有了另一个很酷的模块,它可以为你的代码提供一个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 

真棒不是吗?

由于这些原因,新的髋关节方式是argparse的。 argparse> optparse> getopt

更新:从py2.7开始, argparse是标准库的一部分, optparse已被弃用。

几乎每个人都使用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 

所以总之,这是它的工作原理。

你有两种select。 那些正在接受争论的人,以及那些像开关一样的人。

sys.argv几乎就是C中的char** argv 。就像在C中一样,你跳过第一个元素,它是你程序的名字,只parsing参数: sys.argv[1:]

Getopt.getopt将根据您在参数中给出的规则parsing它。

"ho:v"在这里描述了简短的参数: -ONELETTER 。 这意味着-o接受一个参数。

最后["help", "output="]描述长参数( --MORETHANONELETTER )。 =之后的输出再次意味着输出接受一个参数。

结果是一对夫妇(选项,参数)

如果一个选项不接受任何参数(如--help here), arg部分是一个空string。 然后,您通常要在此列表上循环,并testing选项名称,如示例中所示。

我希望这对你有帮助。

使用标准库附带的optparse 。 例如:

 #!/usr/bin/env python import optparse def main(): p = optparse.OptionParser() p.add_option('--person', '-p', default="world") options, arguments = p.parse_args() print 'Hello %s' % options.person if __name__ == '__main__': main() 

来源: 使用Python来创buildUNIX命令行工具

但是从Python 2.7开始,optparse已经被弃用,请参阅: 为什么要使用argparse而不是optparse?

以防万一你可能需要,如果你需要在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() 

我更喜欢点击 。 它抽象出pipe理选项,并允许“(…)使用尽可能less的代码以可组合的方式创build漂亮的命令行界面”。

以下是示例用法:

 import click @click.command() @click.option('--count', default=1, help='Number of greetings.') @click.option('--name', prompt='Your name', help='The person to greet.') def hello(count, name): """Simple program that greets NAME for a total of COUNT times.""" for x in range(count): click.echo('Hello %s!' % name) if __name__ == '__main__': hello() 

它也自动生成格式良好的帮助页面:

 $ python hello.py --help Usage: hello.py [OPTIONS] Simple program that greets NAME for a total of COUNT times. Options: --count INTEGER Number of greetings. --name TEXT The person to greet. --help Show this message and exit. 

我更喜欢optparse来getopt。 这是非常明确的:你告诉它的选项名称和他们应该有的效果(例如,设置一个布尔字段),它会把你回到根据你的规格填充字典。

http://docs.python.org/lib/module-optparse.html

我认为大型项目的最佳方式是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_ *都暴露在命令行中,并且免费生成一个很好的帮助消息。

 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 

consoleargs值得在这里提到。 这是非常容易使用。 一探究竟:

 from consoleargs import command @command def main(url, name=None): """ :param url: Remote URL :param name: File name """ print """Downloading url '%r' into file '%r'""" % (url, name) if __name__ == '__main__': main() 

现在在控制台中:

 % python demo.py --help Usage: demo.py URL [OPTIONS] URL: Remote URL Options: --name -n File name % python demo.py http://www.google.com/ Downloading url ''http://www.google.com/'' into file 'None' % python demo.py http://www.google.com/ --name=index.html Downloading url ''http://www.google.com/'' into file ''index.html'' 

轻量级命令行参数默认值

尽pipeargparse非常好,并且是完整文档命令行开关和高级function的正确答案,但您可以使用函数参数缺省值来非常简单地处理直接的位置参数。

 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'参数捕获脚本名称,不被使用。 testing输出如下所示:

 > ./test.py a 2 > ./test.py A A 2 > ./test.py A 20 A 20 

对于简单的脚本,我只是想要一些默认值,我觉得这足够了。 您可能还想要在返回值中包含某种types的强制,或者命令行中的值都将是string。

这是一个方法,而不是一个图书馆,似乎为我工作。

这里的目标是简洁,每一个参数用一行parsing,参数排列为可读性,代码很简单,不依赖于任何特殊的模块(只有os + sys),优雅地提醒缺less或未知的参数,使用一个简单的/ range()循环,并在python 2.x和3.x上工作

显示了两个切换标志(-d,-v)和两个由参数(-i xxx和-o xxx)控制的值。

 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]) ### MAIN if __name__=='__main__': verbose = 0 debug = 0 infile = "infile" outfile = "outfile" # Parse command line skip = 0 for i in range(1, 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("%d,%d,%s,%s" % (debug,verbose,infile,outfile)) 

NextArg()的目标是在检查缺less的数据时返回下一个参数,当使用NextArg()时跳过循环,保持标志parsing为一行。