创建并读取配置目录/文件,从配置中设置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反射:高负载下的NoSuchMethodException   java RxJava:one request>list of Integer>sequence of requests for each int>result to list   java为什么循环之前索引会增加   JavaSpring远程处理和RESTfulURL   java Hibernate搜索仅对我的实体的一部分进行索引   使用DPAD快速滚动时,java RecyclerView onCreateViewHolder调用过多   java将JSON解析到一个表中   java导航抽屉标题textview nullpointerexception   基于接口的Java链接队列   java Guice运行时依赖项参数重新注入   java展平/压缩ZSH中的深度嵌套目录   JavaSpring:Http406此请求标识的资源只能   java如何制作Android启动器图标   Java代码在windows上显示不正确(包含希腊语句子)   使用yourkit进行内存分析所用的java时间   java为什么可以序列化属性而不能序列化对象本身?