我原本是C程序员。我看到了许多花招和“技巧”来阅读许多不同的论点。
Python程序员可以通过哪些方式做到这一点?
我原本是C程序员。我看到了许多花招和“技巧”来阅读许多不同的论点。
Python程序员可以通过哪些方式做到这一点?
Answers:
标准库中的规范解决方案是argparse
(docs):
这是一个例子:
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
支持(除其他外):
optparse
已弃用,问题的提问者不再是堆栈溢出的成员,这是一个高度可见的问题的可接受答案-请考虑完全重写示例代码以使用stdlib argparse
代替。
出于这些原因,只是为了使argparse传福音就更好了..本质上:
(从链接复制)
argparse模块可以处理位置和可选参数,而optparse仅可以处理可选参数
argparse对您的命令行界面应该是什么样的并不教条-支持-file或/ file之类的选项,以及必需的选项。Optparse拒绝支持这些功能,而是偏向于纯度而不是实用性
argparse会生成更多有用的用法消息,包括根据您的参数确定的命令行用法,以及有关位置参数和可选参数的帮助消息。optparse模块需要您编写自己的用法字符串,并且无法显示位置参数的帮助。
argparse支持消耗可变数量的命令行args的操作,而optparse要求事先知道确切数量的参数(例如1、2或3)
argparse支持分派到子命令allow_interspersed_args
的解析器,而optparse需要手动设置
和执行解析器分派
和我个人最喜欢的:
add_argument()
使用简单的可调用对象来指定类型和操作参数,而optparse则需要侵入类属性,例如
STORE_ACTIONS
或CHECK_METHODS
进行正确的参数检查。-f
或)指定的参数--foo
,而“事先知道确切数量的参数”大概意味着没有任何前面的选项标志的位置参数。
还有argparse
stdlib模块(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
该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)
如果您需要快速但不太灵活的东西
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
产生以下输出:
你好詹姆斯史密斯
python main.py "James Smith"
这使James Smith
中sys.argv[1]
和产生IndexError
,当您尝试使用不存在的sys.argv[2]
。引用行为在某种程度上取决于您从中运行Python的平台和外壳。
python main.py "James Joseph Smith"
?如果您担心索引超出范围,则可以检查提供的参数数量。无论是否现实,我的示例都显示了如何处理多个参数。
gmail-trash-msg.py MessageID
。此答案直接表明MessageID
已传递了测试参数sys.argv[1]
。
我自己使用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
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构建,并允许您编写如下内容:
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解析工作方式的额外指导。
argh
比其他库或使用起来容易sys
。
argh
但它并不特别适合您最希望不要有带有子命令的命令的场景。
def frobnicate_spleches(...)
定义一个可以执行脚本所执行的功能,然后if __name__ == '__main__': argh.dispatch_command(frobnicate_spleches)
在文件末尾执行的功能似乎是完全可行的。
我的解决方案是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