【发布时间】:2011-10-14 17:31:58
【问题描述】:
我已经使用 optparse 有一段时间了,并且想添加从配置文件加载参数的功能。
到目前为止,我能想到的最好的方法是一个带有硬编码参数的包装批处理脚本......看起来很笨重。
最优雅的方法是什么?
【问题讨论】:
我已经使用 optparse 有一段时间了,并且想添加从配置文件加载参数的功能。
到目前为止,我能想到的最好的方法是一个带有硬编码参数的包装批处理脚本......看起来很笨重。
最优雅的方法是什么?
【问题讨论】:
我同意 S.Lott 使用配置文件的想法,但我建议使用内置的 ConfigParser(3.0 中的 configparser)模块来解析它,而不是自制的解决方案。
这是一个简短的脚本,说明了 ConfigParser 和 optparse 的作用。
import ConfigParser
from optparse import OptionParser
CONFIG_FILENAME = 'defaults.cfg'
def main():
config = ConfigParser.ConfigParser()
config.read(CONFIG_FILENAME)
parser = OptionParser()
parser.add_option("-l",
"--language",
dest="language",
help="The UI language",
default=config.get("Localization", "language"))
parser.add_option("-f",
"--flag",
dest="flag",
help="The country flag",
default=config.get("Localization", "flag"))
print parser.parse_args()
if __name__ == "__main__":
main()
输出:
(<Values at 0x2182c88: {'flag': 'japan.png', 'language': 'Japanese'}>, [])
使用“parser.py --language=French”运行:
(<Values at 0x2215c60: {'flag': 'japan.png', 'language': 'French'}>, [])
帮助是内置的。
使用“parser.py --help”运行:
Usage: parser.py [options]
Options:
-h, --help show this help message and exit
-l LANGUAGE, --language=LANGUAGE
The UI language
-f FLAG, --flag=FLAG The country flag
配置文件:
[Localization]
language=Japanese
flag=japan.png
【讨论】:
我遇到了类似的问题,但也想将配置文件指定为参数。受 S. Lott 的回答启发,我想出了以下代码。
示例终端会话:
$ python defaultconf.py # 使用硬编码的默认值 错误的 $ python defaultconf.py --verbose # 命令行详细 真的 $ python defaultconf.py --loadconfig blah # 加载配置 'verbose':True 真的 $ python defaultconf.py --loadconfig blah --quiet # 覆盖配置值 错误
代码:
#!/usr/bin/env python2.6
import optparse
def getParser(defaults):
"""Create and return an OptionParser instance, with supplied defaults
"""
o = optparse.OptionParser()
o.set_defaults(**defaults)
o.add_option("--verbose", dest = "verbose", action="store_true")
o.add_option("--quiet", dest = "verbose", action="store_false")
o.add_option("--loadconfig", dest = "loadconfig")
return o
def main():
# Hard coded defaults (including non-command-line-argument options)
my_defaults = {'verbose': False, 'config_only_variable': 42}
# Initially parse arguments
opts, args = getParser(my_defaults).parse_args()
if opts.loadconfig is not None:
# Load config from disk, update the defaults dictionary, and reparse
# Could use ConfigParser, simplejson, yaml etc.
config_file_values = {'verbose': True} # the dict loaded from disk
my_defaults.update(config_file_values)
opts, args = getParser(my_defaults).parse_args()
print opts.verbose
if __name__ == '__main__':
main()
一个实用的实现可以在 Github 上找到:The defaults dictionary、the argument parser 和 the main function
【讨论】:
这就是set_defaults 函数的用途。 http://docs.python.org/library/optparse.html#optparse.OptionParser.set_defaults
创建一个作为默认值字典的文件。
{ 'arg1': 'this',
'arg2': 'that'
}
然后读取此文件,对其进行评估以将文本转换为字典,并将此字典作为参数提供给set_defaults。
如果您真的担心eval,那么请对该文件使用 JSON(或 YAML)表示法。或者您甚至可以从中创建一个.INI 文件并使用configparser 来获取您的默认值。
或者您可以使用简单的赋值语句列表和exec。
配置文件。
arg1 = 'this'
arg2 = 'that'
读取配置文件。
defaults= {}
with open('defaults.py','r') as config
exec config in {}, defaults
【讨论】:
以相同的命令行格式从文件中读取参数,例如@commands,然后使用您的原始解析器来解析它们。
options, args = parser.parse_args()
if args[0][0] == '@': # script.py @optfile
with open(args[0][1:]) as f:
fa = [l.strip() for l in f]
fa = fa + args[1:] # put back any other positional arguments
# Use your original parser to parse the new options
options, args = parser.parse_args(args=fa, values=options)
【讨论】: