创建并读取配置目录/文件,从配置中设置argparse(sub)解析器默认值

ruamel.appconfig的Python项目详细描述


此模块提供了一种方法,可以轻松地将配置目录和文件添加到 申请。配置目录可用于 特定于用户的数据文件。:

.. example output clean.py

默认情况下,它使用ruamel.yaml 供阅读和 写入配置文件,因为此库保留任何 添加了注释(pythons拥有的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,
)

结果:

created directory /home/a114/.config/appconfigbasic

默认情况下(在linux/macos上),config目录创建于 ~/.config,默认配置文件是 ~/.config/appconfigbasic/appconfigbasic.ini(这个appconfigbasic 传递给AppConfig()的值。在那之前 测试该文件是否已经存在,或是否 ~/.appconfigbasic/appconfigbasic.ini~/.appconfigbasic.ini 存在。

在windows上,配置目录是$APPDATA/appconfigbasic

与argparse的交互

AppConfig()还有其他选项可以与argparse参数解析进行交互:

  • 它可以填写应用程序选项的默认值 (包括那些次犯罪者的选择)。
  • 它可以添加一个--config选项,允许用户指定 配置文件的备用路径。
  • 它可以添加一个--save-defaults,用户可以用它保存值 对于命令行中指定的选项,转到配置文件。全球的 选项存储在配置的[global]部分 文件,在具有supparser名称的节中为子parser提供选项。

添加--config

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

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.argparsedecorators的交互

因为ruamel.std.argparsedecorator是一个包装器 围绕正常的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

有输出(请注意xyz是默认的,因为配置 在AppConfig实例化之前写入的文件:

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

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

推荐PyPI第三方库


热门话题
java Spinner选定值未上载到firebase数据库   java如何通过bukkit中的配置添加消息?   java在SharedReference中保存列表的泛型类型   javascript Java小程序未定义   swt在Java中构建控制台应用程序   java OAuth同意屏幕没有突然显示,没有错误?   java webview选择文件安卓不工作   java Spring boot JPA如何从同一连接添加多个数据库?   java JDBC DB2驱动程序计时器线程处于阻塞状态   java我在vscode中运行flatter时看到一个错误在phone中运行应用程序somone能否帮助我plz   Java:生成JSON:如何避免生成不完整的JSON   java Date compareTo()方法始终返回1   当使用Junit runner运行测试时,java Spring自动连线失败   java Android/Sockets如何将信息从主UI线程发送到socket线程?   java Android内存声明全局变量   java如何在JBoss中拥有多个具有相同JNDI名称的数据源?   python在Java中嵌入CPython时,为什么会挂起?   java如何提供深度模拟对象?   java“find:smallint,expected:integer”Hibernate对informix数据库的验证在短时间内失败