Python 使用文件存储optpass参数

Python 使用文件存储optpass参数,python,optparse,Python,Optparse,我已经使用optparse一段时间了,我想添加从配置文件加载参数的功能 到目前为止,我能想到的最好的方法是使用硬编码参数的包装器批处理脚本。。。看起来很笨重 最优雅的方式是什么 这就是set\u defaults函数的作用 创建一个作为默认值字典的文件 { 'arg1': 'this', 'arg2': 'that' } 然后读取此文件,对其求值以将文本转换为字典,并将此字典作为参数提供给set\u defaults 如果您真的担心eval,那么对该文件使用JSON(或YAML)表示法。或者您

我已经使用optparse一段时间了,我想添加从配置文件加载参数的功能

到目前为止,我能想到的最好的方法是使用硬编码参数的包装器批处理脚本。。。看起来很笨重


最优雅的方式是什么

这就是
set\u defaults
函数的作用

创建一个作为默认值字典的文件

{ 'arg1': 'this',
'arg2': 'that'
}
然后读取此文件,对其求值以将文本转换为字典,并将此字典作为参数提供给
set\u defaults

如果您真的担心
eval
,那么对该文件使用JSON(或YAML)表示法。或者您甚至可以从中生成一个
.INI
文件,并使用
configparser
获取默认值

或者,您可以使用简单的赋值语句列表和
exec

配置文件

arg1 = 'this'
arg2 = 'that'
正在读取配置文件

defaults= {}
with open('defaults.py','r') as config
    exec config in {}, defaults

我同意S.Lott使用配置文件的想法,但我建议使用内置(3.0中的configparser)模块来解析它,而不是使用自制的解决方案

下面是一个简短的脚本,它演示了ConfigParser及其实际应用

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'}>, [])
[Localization]
language=Japanese
flag=japan.png
帮助是内在的。 使用“
parser.py--help
”运行:

配置文件:

(<Values at 0x2182c88: {'flag': 'japan.png', 'language': 'Japanese'}>, [])
[Localization]
language=Japanese
flag=japan.png
您可以使用该模块:

>>> open('args.txt', 'w').write('-f\nbar')
>>> parser = argparse.ArgumentParser(fromfile_prefix_chars='@')
>>> parser.add_argument('-f')
>>> parser.parse_args(['-f', 'foo', '@args.txt'])
Namespace(f='bar')

它可能包含在stdlib中,请参见。

我遇到了类似的问题,但也希望将配置文件指定为参数。受S.洛特答案的启发,我想出了以下代码

终端会话示例:

$ python defaultconf.py # use hard-coded defaults False $ python defaultconf.py --verbose # verbose on command line True $ python defaultconf.py --loadconfig blah # load config with 'verbose':True True $ python defaultconf.py --loadconfig blah --quiet # Override configured value False
可以在Github上找到一个实用的实现:,并从文件(例如@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)

最近,我构建了很多带有标志和选项的脚本,并提出了所描述的解决方案

基本上,我使用一个带有特殊标志的optionparser实例,该标志告诉您尝试从文件中加载选项,因此您可以正常使用脚本,从命令行指定选项,或者从文件中提供选项(或一组选项)


更新:我在

上共享了代码,这里没有理由使用eval-你可以使用marshal。@Nick Bastin:eval不是邪恶的,只有那些反社会的最终用户,他们总是试图利用eval的使用来攻击应用程序。利用你盔甲上的裂缝向攻击者挥动手指既不能消除裂缝,也不能阻止攻击…:)@凯文·利特尔:这个神秘的“攻击者”是谁?同事?购买应用程序的人?具体是谁?请提供这位神秘的“攻击者”的姓名。@S.Lot;):我不知道这个神秘的攻击者是谁——这就是问题的一部分!我也不知道这个小小的“安全的”Python小程序在哪,比如说,三年后,会在其中插入一个外部可访问文件的裸体“eval()”。也许它会成为我从未想象过的一项漂亮的公共服务的一部分,通过信任我在写这本书一年后离开的公司/社区中的开发人员,巧妙地融合在一起。但是,我们离题了;很抱歉PEP389已经获得批准,
argparse
已经是Python 2.7的一部分,这太棒了。我对其进行了扩展,在--help中还显示了配置文件中的默认值:
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)