跳转到主要内容

创建和读取配置目录/文件,从配置设置argparse(子)解析器的默认值

项目描述

此模块提供了一种轻松向应用程序添加配置目录和配置文件的方法。配置目录可以用于存储额外的用户特定数据文件。

默认情况下,它使用ruamel.yaml来读取和写入配置文件,因为这个库保留了任何添加的注释(而Python自己的ConfigParser会丢弃这些注释)。

基本调用方式是

from __future__ import print_function

import sys

from ruamel.appconfig import AppConfig

def to_stdout(*args):
    sys.stdout.write(' '.join(args))

ac = AppConfig(
    'appconfigbasic',  # name of config diretory, normally the application name
    warning=to_stdout,
)
from __future__ import print_function

import sys

from ruamel.appconfig import AppConfig


def to_stdout(*args):
    sys.stdout.write(' '.join(args))


ac = AppConfig(
    'appconfigbasic',  # name of config directory, normally the application name
    warning=to_stdout,
)

结果为

created directory /home/a114/.config/appconfigbasic

默认情况下(在Linux/macOS上),配置目录位于~/.config下,默认配置文件将是~/.config/appconfigbasic/appconfigbasic.iniappconfigbasic是传递给AppConfig()的值)。在此之前,会检查该文件是否已存在,或者是否已存在~/.appconfigbasic/appconfigbasic.ini~/.appconfigbasic.ini

在Windows上,配置目录应为$APPDATA/appconfigbasic

与argparse的交互

AppConfig()具有与argparse参数解析交互的额外选项

  • 它能够填充应用程序选项的默认值(包括子解析器的选项)。

  • 它可以添加一个--config选项,允许用户指定配置文件的替代路径。

  • 它可以将一个 --save-defaults 参数添加到配置文件中,用户可以使用该参数将命令行中指定的选项的值保存到配置文件中。全局选项存储在配置文件的 [global] 部分,子解析器的选项存储在具有子解析器名称的章节中。

添加 --config

要添加此选项,请传入解析器并将 filename 参数设置到 AppConfig.check 属性

from __future__ import print_function

from argparse import ArgumentParser
from ruamel.appconfig import AppConfig

parser = ArgumentParser()

ac = AppConfig(
    'appconfigconfig',
    parser=parser,  # needed to set new options
    filename=AppConfig.check,  # sets --config option
)

parser.parse_args(['--help'])

结果为

usage: addconfig.py [-h] [--config FILE]

optional arguments:
  -h, --help     show this help message and exit
  --config FILE  set FILE as configuration file
                 [~/.config/appconfigconfig/appconfigconfig.ini]

设置默认值和添加 --save-defaults

要将默认值保存到配置文件

from __future__ import print_function

from argparse import ArgumentParser
from ruamel.appconfig import AppConfig

parser = ArgumentParser()

parser.add_argument('--delete', '-d', default='bla',
                    help='delete a file (default: %(default)s)')
parser.add_argument('--owner', default='itsme',
                    help='set owner (default: %(default)s)')
parser.add_argument('--force', action='store_true',
                    help='force action (default: %(default)s)')
ac = AppConfig(
    'addconfigsave',
    parser=parser,  # needed to set new options
    filename=AppConfig.check,  # sets --config option
    add_save=True,  # add save option
)
ac.set_defaults()  # set the ArgumentParser() defaults
# and save to config file
args = ac.parse_args(['--delete', 'two', '--save-defaults'])

with open(ac.get_file_name()) as fp:
    print(fp.read())

结果为

[global]
delete = two
owner = itsme
force = False

ruamel.std.argparse 装饰器的交互

由于 ruamel.std.argparse 装饰器是围绕正常 argparse 使用的一个包装器,因此添加 AppConfig() 非常简单

from __future__ import print_function

import sys
import os

from ruamel.std.argparse import ProgramBase, option, sub_parser, version, \
    SmartFormatter


class TestCmd(ProgramBase):
    def __init__(self):
        super(TestCmd, self).__init__(
            formatter_class=SmartFormatter
        )

    # you can put these on __init__, but subclassing TestCmd
    # will cause that to break
    @option('--quiet', '-q', help='suppress verbosity', action='store_true',
            global_option=True)
    @version('version: 1.2.3')
    def _pb_init(self):
        # special name for which attribs are included in help
        pass

    def run(self):
        if self._args.func:
            return self._args.func()

    def parse_args(self, *args):
        from ruamel.appconfig import AppConfig
        app = 'addconfigcomplex'
        # pre populate config file
        with open(os.path.expanduser(
            '~/.config/{}/{}.ini'.format(app, app)), 'w') as fp:
            fp.write('[readit]\nname=XYZ\n')
        self._config = AppConfig(
            app,
            parser=self._parser,  # self._parser set by ProgramBase
            filename=AppConfig.check,  # sets --config option
            add_save=True,  # add save option
        )
        self._config.set_defaults()
        self._parse_args(*args)

    @sub_parser(help='specific help for readit')
    @option('--name', default='abc',
            help='help for name (default: %(default)s)')
    def readit(self):
        print('calling readit')

    @sub_parser('writeit', help='help for writeit')
    @option('--target')
    def other_name(self):
        print('calling writeit')


n = TestCmd()
n.parse_args(['readit', '--help'])  # normaly no parameters -> sys.argv
n.run()  # never reached

有输出(请注意,因为配置文件是在 AppConfig 实例化之前编写的,所以 XYZ 是默认值)

usage: complex.py readit [-h] [--name NAME] [--quiet] [--save-defaults]

optional arguments:
  -h, --help       show this help message and exit
  --name NAME      help for name (default: XYZ)
  --quiet, -q      suppress verbosity
  --save-defaults  save option values as defaults to config file

支持者

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误日志 StatusPage StatusPage 状态页面