Python实现一个强大的配置库

应用程序经常要读取配置文件,还要验证输入是否有效、没有配置时使用默认值,于是我就想怎么简化这一流程

文件格式

首先为了方便用户直接改写,文件格式一定要是可读的。Python 标准库里可以读写可读配置的库有 configparser(ini文件)、json、xml,其中 ini、xml 文件不分类型,读取到的都是字符串,所以选择了 json。不过 JSON 有个缺点就是不支持注释,可以忽略这个缺点,提供好文档就行了

数据验证、默认值

我找到了一个 Python 库:trafaret,它可以验证任何形式的数据并转换成需要的格式

这是把一个 dict 转换成 datetime 的例子:

import datetime
import trafaret as t

date = t.Dict({
    'year': t.Int,
    'month': t.Int,
    'day': t.Int
}) >> (lambda d: datetime.datetime(**d))
assert date.check({
  'year': 2012, 'month': 1, 'day': 12}) == datetime.datetime(2012, 1, 12)

首先声明个 Dict 结构,指定 key 和值的类型, >> 操作符可以指定自定义的转换函数,转换函数中可以抛出 DataError 错误, date.check() 可以返回验证并转换后的对象

Dict 的 key 除了字符串,还可以指定 Key 类型,Key 可以指定默认值以及把原名字转换成另一个名字:

>>> c = t.Dict({t.Key('un', 'default_user_name', True) >> 'user_name': t.String})
>>> c.check({
  'un': 'Adam'})
{
  'user_name': 'Adam'}
>>> c.check({})
{
  'user_name': 'default_user_name'}

这是声明一个可选的 key 叫 'un',默认值是 'default_user_name'>> 操作符指定读取后名字转换成 'user_name',也可以在参数里指定转换的名字

实现 Config 类

trafaret 转换后得到的是 dictdict 用的是字符串类型的 key,这对编辑器不友好,写代码时没有自动补全,而且想改名时也没办法自动批量修改,所以我打算用访问属性的方式访问配置(用 . 操作符访问)

受到各种 ORM 框架的启发,我打算在类属性里声明配置的字段,写法如下:

class NestedConfig(config):
    pass


class MyConfig(Config):
    bool_field = {OptionalKey(True): t.Bool}
    int_field = {OptionalKey(123): t.Int}
    nested_config = {OptionalKey({}): NestedConfig}

OptionalKey

这其实就是指定了一些默认参数的 Key 类,这样我们在参数里就只用写默认值了,转换后的名字由类属性的名字指定

class OptionalKey(t.Key):
    def __init__(self, default, name=None):
        super().__init__(name, default, True)

将声明的字段转换成 Dict

用 Python 的元类可以很容易实现这一点,我们在创建类时扫描声明的字段,转换成 Dict 并保存在 __struct__ 类属性里。这里还实现了 Config 的继承,只要在创建 __struct__ 的时候把基类已经创建好的 __struct__ 合并进去就行了,注意基类不能覆盖子类的字段

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值