Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
通过argparse python从cfg文件动态设置默认值_Python_Python 2.7_Argparse - Fatal编程技术网

通过argparse python从cfg文件动态设置默认值

通过argparse python从cfg文件动态设置默认值,python,python-2.7,argparse,Python,Python 2.7,Argparse,我正在尝试使用argparse模块。我正在处理2个配置文件: 1.默认的cfg文件2。用户提供的文件 如果在运行时未提供文件,请从默认文件读取。如果用户提供了文件,请使用提供的文件的内容 我的问题是:我想为每个解析器提供默认值字段。添加_agment,这样,如果不是用户提供的,它将始终具有一些默认值。这些值可以从任一文件(即默认文件或用户给定文件)中读取。我需要检查提供了哪个文件,然后从默认/用户指定的文件导入 我的代码: 获取args.py class GetArgs: def get_

我正在尝试使用
argparse
模块。我正在处理2个配置文件:
1.默认的cfg文件2。用户提供的文件

如果在运行时未提供文件,请从默认文件读取。如果用户提供了文件,请使用提供的文件的内容

我的问题是:我想为每个
解析器提供
默认值
字段。添加_agment
,这样,如果不是用户提供的,它将始终具有一些默认值。这些值可以从任一文件(即默认文件或用户给定文件)中读取。我需要检查提供了哪个文件,然后从默认/用户指定的文件导入

我的代码:
获取args.py

class GetArgs:
   def get_args(self):
       parser = argparse.ArgumentParser(description='foo')
       #
       parser.add_argument(
        '-c', '--config', type=str, help='Provide a file', 
                          required=False, default='settings.cfg')
         #now note that below "default=version" will be from either "settings.cfg" or "user given file"

         # here may be i need to import from file ? 
        parser.add_argument(
        '-v','--version', type=str, help='API version', required=False, default=version)
        args = parser.parse_args()

        # Assign args to variables
        config=args.config
        version = args.version
        retutn config,version
读取cfg文件的代码: read_file.py

import ConfigParser
configParser = ConfigParser.RawConfigParser()
configParser.read(file)
try:
    version= configParser.get('Set', 'version')
    ....
    ....
except ConfigParser.NoOptionError:
    print "Option not found in configuration file!"
    sys.exit(1)
比如:

1.python get_args.py                                      #reads "version" from settings.cfg
2.python get_args.py --config /path/to/file/file.cfg      #reads "version" file.cfg   
当我不提供--config时,它可以完美地工作

这可以动态读取吗?

动态填充解析器 今天的另一个问题得到了一个答案,说明了如何从字典中的值填充解析器:

伊皮顿也做了类似的事情。它读取配置文件(默认配置文件和用户配置文件),并使用配置值创建解析器。这为用户提供了几个级别的控制——默认配置、概要配置,最后是命令行。但Ipython代码相当复杂

编辑参数值 另一个有用的观点是,每个参数或操作对象在创建后都可用,并且可以(在限制范围内)进行修改

arg1 = parser.add_argument('--foo', default='test', ...)
# arg1 is an Action object with the various parameters
print arg1     # a display of some attributes
print arg1.default    # the value of the default as set above
arg1.default = 'different'  # assign a new value
因此,可以在解析之前动态设置默认值

前缀字符文件 另一个有用的工具是

允许我指定以字符开头的文件名。它将读取文件内容并将字符串拼接到
sys.argv
列表中,就像我键入了它一样

解析后填写默认值 但是,如果您想在命令行中指定配置文件,然后使用其内容为解析器设置默认值,事情会变得更复杂

解析后,
args
将是一个名称空间对象,其中包含配置文件名及其解析的所有其他参数

您可以使用
print args
查看
args
的确切内容,或者以字典形式查看
vars(args)
。关于哪些值是由解析器默认值设置的,哪些值是由命令行设置的,没有隐藏的信息

默认值的最干净的解析后测试是

if args.foo is None:
   # this has the default default
如果值为
None
,则只能来自默认值,而不能来自命令行(没有转换为
None
)的字符串)

因此,我可以想象编写一个函数,遍历
vars(args)
的键,测试
None
,并用
config
中的相应值替换它。(你需要帮忙吗?)

如果
config
args
都被强制转换为兼容的字典,则可以使用dictionary
update
方法将值从一个转换到另一个

如果参数未出现在命令行中,则可以使用
default=argparse.SUPPRESS
将参数保留在命名空间之外。这可以与字典更新一起使用,例如

config_dict.update(vars(args))
只会更改命令行中给定参数的配置

两级解析器 另一个想法是使用两阶段解析。定义一个具有
config_文件
参数的解析器,而没有(或很少)其他解析器。使用
parse_known_args
运行它,以获取
config_文件
值。读取配置文件并使用它填充第二阶段解析器(或至少修改其默认值)。现在运行第二阶段解析器以获得完整的名称空间(我只需忽略此参数中的任何
config\u文件
值)

链图

一个新的
collections
类,
ChainMap
有一个从名称空间、env、defaults等进行链式值查找的示例

namespace = parser.parse_args() 
command_line_args = {k:v for k, v in vars(namespace).items() if v} 
combined = ChainMap(command_line_args, os.environ, defaults) 
print(combined['color'])


其他关于

的好主意我不认为您想要实现什么是可能的,因为必须在解析参数之前设置默认值–例如,在调用
/get_args.py-h
时显示默认值非常重要。但是,您可以将默认值设置为
None
,然后用从任一配置文件中读取的值替换这些值。@DavidZwicker-Yes在执行脚本之前设置默认值是有意义的。
namespace = parser.parse_args() 
command_line_args = {k:v for k, v in vars(namespace).items() if v} 
combined = ChainMap(command_line_args, os.environ, defaults) 
print(combined['color'])