将多个配置文件和命令行参数合并到单个配置中

ArgConfigParse的Python项目详细描述


ArgConfigParse

使用python标准argparse和configparser模块将命令行参数和配置文件合并到一个字典中。在

ArgConfigParse提供以下类和函数:

  • ConfigFile()
  • CmdArg()

函数

  • merge_dict()
  • fullPath()

ConfigFile读取一个或多个配置文件,并将每个配置文件与以下文件进行破坏性合并。在每个后续配置文件中重复的任何键/值对都将有效地重写同一个键的先前值。这对于处理可以被单个用户配置文件覆盖的系统范围配置文件非常有用。在

CmdArg分析系统argv命令行参数,并创建可与配置文件中的值轻松合并的嵌套词典。在

未出现在配置文件中的命令行参数存储在__cmd_line

示例

ConfigFile()示例

类来处理多个类似的配置文件并按顺序合并内容。在

系统范围的配置文件

    #/etc/spam_sketch
    [Main]
    menu = ["spam", "eggs and spam"]
    debug = INFO
    output_device = dead_parrot


    [waiter]
    name = Terry
    tone = shrill
    attempts = 10
    pause = False

用户配置文件

^{pr2}$

读取配置文件

    import ArgConfigParse
    # read /etc/spam_sketch followed by ~/.config/spam_sketch 
    # values in ~/.config/spam_sketch override /etc/spam_sketch
    config = ArgConfigParse.ConfigFile(['/etc/spam_sketch', '~/.config/spam_sketch'])

    config.parse_config()
    print(config.config_dict)
    >>> {'Main': {'menu': '["spam", "eggs and spam", "spam; spam; spam and eggs", "eggs; spam spam and toast"]', 'debug': 'DEBUG', 'output_device': 'dead_parrot'}, 'waiter': {'name': 'John', 'tone': 'shrill', 'attempts': '10', 'pause': 'False'}, 'customer1': {'name': 'Eric', 'patience': '.8', 'order': '"anything but spam"'}, 'customer2': {'name': 'Graham', 'patience': '.2', 'order': '"toast"'}}

CmdArg()示例

Parse命令行参数

    import ArgConfigParse
    # create the argument parser object
    cmd_args = CmdArgs()
    # set some toy sys.arv values
    sys.argv = ['-V', '-m', ['spam', 'toast and spam', 'one dead parrot']]

    # add arguments to be accepted from the command line

    # this option will be stored in {'main': {'menu': <list>'}}
    cmd_args.add_argument('-m', '--menu', ignore_none=True, 
                          metavar='["item one", "item two", "item three"]', 
                          type=list,
                          dest='main__menu', 
                          help='list of menu items')


    # this option will be stored in {'waiter':{'tone': <value>'}}
    cmd_args.add_argument('-t', '--tone', ignore_none=True, metavar='TONE', type=str,
                           choices=['kind', 'shrill', 'annoying', 'loud'], dest='waiter__tone', 
                           help='tone of waiter')

    # this option will be stored in __cmd_line 
    cmd_args.add_argument('-V', '--version', action='store_true', dest='version', 
                          default=False, help='display version nubmer and exit')


    # parse sys.argv values
    cmd_args.parse_args()

    # show parsed values
    print(cmd_args.options)
    >>> Namespace(main__menu=['spam', 'toast and spam', 'one dead parrot'], main__output_device=None, version=True, waiter__tone=None)

    # show nested dictionary
    print(cmd_args.nested_opts_dict)
    >>> {'__cmd_line': {'version': True}, 'main': {'menu': ['spam', 'toast and spam', 'one dead parrot']}}

merge_dict()示例

Merge命令行参数和配置文件

    # command line options override config files
    options = merge_dict(config.config_dict, cmd_args.nested_opts_dict)
    print(options)
    >>> {'__cmd_line': {'version': True}, 'main': {'menu': ['spam', 'toast and spam', 'one dead parrot']}, 'Main': {'menu': '["spam", "eggs and spam", "spam; spam; spam and eggs", "eggs; spam spam and toast"]', 'debug': 'DEBUG', 'output_device': 'dead_parrot'}, 'waiter': {'name': 'John', 'tone': 'shrill', 'attempts': '10', 'pause': 'False'}, 'customer1': {'name': 'Eric', 'patience': '.8', 'order': '"anything but spam"'}, 'customer2': {'name': 'Graham', 'patience': '.2', 'order': '"toast"'}}



    # config files override command line options
    options merge_dict(cmd_args.nested_opts_dict, config.config_dict,)
    print(options)
    >>> {'Main': {'menu': '["spam", "eggs and spam", "spam; spam; spam and eggs", "eggs; spam spam and toast"]', 'debug': 'DEBUG', 'output_device': 'dead_parrot'}, 'waiter': {'name': 'John', 'tone': 'shrill', 'attempts': '10', 'pause': 'False'}, 'customer1': {'name': 'Eric', 'patience': '.8', 'order': '"anything but spam"'}, 'customer2': {'name': 'Graham', 'patience': '.2', 'order': '"toast"'}, '__cmd_line': {'version': True}, 'main': {'menu': ['spam', 'toast and spam', 'one dead parrot']}}    

文件

类CmdArgs(builtins.object)

 |  CmdArgs(args=None)
 |  
 |  command line argument parser object 
 |  
 |  
 |  
 |  
 |  Args:
 |      args(`list`): sys.argv is typically passed here
 |      
 |  Properties:
 |      parser(`argparse.ArgumentParser`): argument parser object
 |      args(`list`): list of arguments
 |      unknown(`list`): list of unknown arguments that are ignored
 |      options(NameSpace): argument parser generated namespace of arguments
 |      opts_dict(`dict`): namespace -> dictionary
 |  
 |  Methods defined here:
 |  
 |  __init__(self, args=None)
 |      Initialize self.  See help(type(self)) for accurate signature.
 |  
 |  add_argument(self, *args, **kwargs)
 |      add arguments to the parser.argparse.ArgumentParser object 
 |          use the standard *args and **kwargs for argparse
 |          
 |          arguments added using the kwarg `dest=section__option_name`
 |          note the format [[section_name]]__[[option_name]]
 |          will be nested in the `opts_dict` property in the format:
 |          {'section': 
 |                      {'option_name': 'value'
 |                       'option_two': 'value'}}
 |                       
 |          the `nested_opts_dict` property can then be merged with a ConfigFile 
 |          `config_dict` property using the merge_dicts() function:
 |          merge_dicts(obj:`ConfigFile.config_dict`, obj:`Options.nested_opts_dict`) 
 |          to override the options set in the configuration file(s) with
 |          commandline arguments
 |      
 |      Args:
 |          ignore_none(`bool`): ignore this option if set to `None` when building configuration dictionary
 |          ignore_false(`bool`): ignore this option if set to `False` when building configuation dictionary
 |          *args, **kwargs
 |  
 |  parse_args(self)
 |      parse arguments and set dictionaries
 |          
 |      Sets:
 |          args(`list`): list of arguments
 |          unknown_args: args that have been passed, but are not known
 |          options(Nampespace): namespace of parsed known arguments
 |          opts_dict(`dict`): flat dictionary containing arguments
 |          nested_opts_dict(`dict` of `dict` of `str`): parsed arguments
 |              nested to match ConfigFile.opts_dict:
 |              {'section_name': {'option1': 'valueY'
 |                                'option2': 'valueZ'}
 |                                
 |               'section_two':  {'optionX': 'setting1'
 |                                'optionY': 'other_setting'}}
 |                                
 |          see add_argument() for more information

类配置文件(builtins.object)

 |  ConfigFile(config_files=None)
 |  
 |  Read and parse one or more INI style configuration files
 |  
 |      Creates a configparser.ConfigParser() object and reads multiple
 |      configuration files. Settings in each file supersedes pervious files
 |      `config_files`=[default, system, user] 
 |      * default - read first
 |      * system - read second and overwrites default
 |      * user - read last and overwrites system
 |      
 |  Args:
 |      config_files(`list`): list of configuration files to read
 |  Properties:
 |      config_files(`list` of `str` or `pathlib.PosixPath`): str or Path() objects to read
 |      parser(`configparser.ConfigParser obj`): config parser object
 |      config_dict(`dict` of `dict`): nested configuration dict following INI file format:
 |          Sample config.ini:
 |          
 |              [Section]
 |              option = value
 |              option2 = True
 |  
 |              [Main]
 |              log_level = DEBUG
 |          
 |          Yeilds -> config_dict:
 |          
 |              {'Section': {'option': 'value', 'option2': True}
 |               'Main': {'log_level': 'DEBUG'}}
 |  
 |  Methods defined here:
 |  
 |  __init__(self, config_files=None)
 |      Initialize self.  See help(type(self)) for accurate signature.
 |  
 |  parse_config(self)
 |      reads and stores configuration values from `config_files` in left-to-right order
 |          right-most section/option/values overwrite left-most section/option/values
 |      
 |      Returns:
 |          config_dict(`dict` of `dict`)
 |      Sets: config_dict

合并(a,b)

recursivley merge two dictionarys overwriting values
    known issue: if `a` contains a different data type than `b`, 
    `b` will completely overwrite the data in `a`

Args:
    a(`dict`): nested dictionary
    b(`dict`): nested dictionary 

Returns:
    `dict`

写入(dictionary,file,create=False)

Help on function write in module __main__:

write(dictionary, file, create=False)
    write a configuration dictionary to a file; skip over sections that begin with `__`

    Args: 
        dictionary(`dict`): nested dictionary
        file(`string` or `Path`): path to config file
        create(`bool`): create the file and path if it does not exist

    Returns:
        file(`Path`): path to config file

局限性

配置文件节名不能包含以下字符:

  • '__'——连续两个或多个下划线
    • 好:main_section
    • 好:waiter_configuration_settings
    • 不正常:main__section——这将导致选项字典中出现意外的嵌套节
  • ' '——一个或多个文本空间

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java无法使用Oauth找到我的项目的服务器客户端机密   JAVAlang.NullPointerException:null   java如何将图像放在安卓 studio的导航抽屉项目后面?示例如下所示   java结构,并将两个数组发送到同一个接收函数   javafx Java FX(FXML)设置禁用   jakarta ee使用Java修改jar文件中的xml文件   支持OpenGL ES 3.0的Android 3D Java开源游戏引擎   java运行构建失败或成功取决于以前的构建   java计算数组的平均值   java如何在可运行jar程序中获取资源jar路径?   swing在JAVA中从序列化中读回一个文件后,如何获得一个新的Graphics2D对象?   java Leetcode 833:字符串替换取决于索引编号   UbuntuPayara 5.194,带有Ubuntu16和Java 8,由于JLine抛出了UnsupportedOperationException而失败   java为什么int变量在分配给字节变量时抛出错误,而不是int文本?   java获取类的方法   如何将数字列表保存在数据库中。java中的txt文件?   Java中的scala Gatling DSL   java克隆Swing组件