• Python配置文件实现


    实现目标:

    • 支持配置文件继承
    • 支持本地配置文件
    • 支持配置文件别名
    • 简单的配置文件操作

    最新的代码可以参考 https://github.com/blackmatrix7/matrix-toolkit/blob/master/toolkit/config.py

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    # @Time : 2017/8/18 上午9:31
    # @Author : Matrix
    # @Github : https://github.com/blackmatrix7/
    # @Blog : http://www.cnblogs.com/blackmatrix/
    # @File : config.py
    # @Software: PyCharm
    import os
    
    __author__ = 'blackmatrix'
    
    
    class ConfigMixin:
    
        """
        Config混合类,支持部分dict协议,实现以类似操作dict的方式操作配置文件。
        """
    
        def __setattr__(self, key, value):
            raise AttributeError
    
        def __setitem__(self, key, value):
            raise AttributeError
    
        def __delitem__(self, key):
            raise AttributeError
    
        def __getitem__(self, item):
            try:
                return getattr(self, item)
            except AttributeError as ex:
                raise KeyError('{0} object has no key {1}'.format(self.__class__.__name__, item)) from ex
    
        def __iter__(self):
            return (k for k in dir(self) if k.upper() == k)
    
        def __contains__(self, key):
            return hasattr(self, key)
    
        def items(self):
            return {k: getattr(self, k, None) for k in dir(self) if k.upper() == k}.items()
    
        def get(self, item, value=None):
            return getattr(self, item, value)
    
    
    class BaseConfig(ConfigMixin):
        """
        配置文件基类
        """
        # 项目路径
        PROJ_PATH = os.path.abspath('')
    
    
    def get_current_config(config_name='default'):
        """
        对本地配置文件的支持,当项目根目录存在localconfig.py文件时
        优先从localconfig.py中读取配置,如果不存在读取config.py的配置。
        localconfig.py 应该加入git的忽略文件
        :return:
        """
        try:
            from localconfig import configs
            current_config = configs[config_name]
        except ImportError:
            from config import configs
            current_config = configs[config_name]
        return current_config

    使用示例:

    在项目根目录创建 config.py 和 localconfig.py。

    localconfig.py可以不创建(如果不需要本地配置文件的话),如果创建localconfig.py,需要在.gitignore中,将localconfig.py排除掉。

    当项目根目录同时存在config.py 和 localconfig.py时,优先读取localconfig.py的配置项。

    config.py 完整代码:

    from toolkit.config import BaseConfig, get_current_config
    
    __author__ = 'blackmatrix'
    
    
    class DefaultConfig(BaseConfig):
    
        """
        配置文件的具体实现,所有的配置项都必须是全部大写
        """
    
        # DEBUG
        DEBUG = False
    
        # Cache
        CACHE_MEMCACHED_SERVERS = ['127.0.0.1:11211']
        CACHE_KEY_PREFIX = ''
    
        # RabbitMQ
        RABBITMQ_HOST = '127.0.0.1'
        RABBITMQ_PORT = 5672
        RABBITMQ_USER = 'user'
        RABBITMQ_PASS = 'password'
    
    
    """
    以下为测试用数据
    """
    
    
    class BaseDemoConfig(BaseConfig):
    
        # HOST
        HOST = '127.0.0.1'
    
        """
        对于需要通过其他属性运算获得的属性参数,需要定义在特性中
        """
        LOGIN_URL = property(lambda self: 'http://{host}/login'.format(host=self.HOST))
    
    
    class DemoConfig01(BaseDemoConfig):
        # HOST
        HOST = '192.168.1.10'
    
    
    class DemoConfig02(BaseDemoConfig):
        # HOST
        HOST = '10.10.10.10'
    
    
    default = DefaultConfig()
    demo01 = DemoConfig01()
    demo02 = DemoConfig02()
    
    
    configs = {'default': default,
               'demo01': demo01,
               'demo02': demo02}
    
    # 读取配置文件的名称,在具体的应用中,可以从环境变量、命令行参数等位置获取配置文件名称
    config_name = 'default'
    
    current_config = get_current_config(config_name)

    在config.py模块中:

    每套配置都为独立的类,继承自BaseConfig,并将其实例化。

    如有必要,在多套配置文件类中,可以互相继承。比如DemoConfig01继承自BaseDemoConfig。

    在配置文件类的继承中,比较特别的是需要通过其他属性参与运算获取的配置项,需要使用property定义。

    例如下面示例代码的LOGIN_URL,需要通过HOST计算得来。

    那么就必须写成 LOGIN_URL = property(lambda self: 'http://{host}/login'.format(host=self.HOST))

    而不能写成 LOGIN_URL = 'http://{host}/login'.format(host=self.HOST) ,否则在配置文件类的继承时,会出现和预想不一致的情况。

    因为在父类(BaseDemoConfig)创建的时候,LOGIN_URL已经通过计算生成。

    子类(DemoConfig01)继承自BaseDemoConfig,即使对HOST进行修改,也不会影响到LOGIN_URL的值。那么子类的LOGIN_URL一直是父类创建时的状态。

    class BaseDemoConfig(BaseConfig):
    
        # HOST
        HOST = '127.0.0.1'
    
        """
        对于需要通过其他属性运算获得的属性参数,需要定义在特性中
        """
        LOGIN_URL = property(lambda self: 'http://{host}/login'.format(host=self.HOST))
    
    
    class DemoConfig01(BaseDemoConfig):
        # HOST
        HOST = '192.168.1.10'
    
    
    class DemoConfig02(BaseDemoConfig):
        # HOST
        HOST = '10.10.10.10'
    
    
    default = DefaultConfig()
    demo01 = DemoConfig01()
    demo02 = DemoConfig02()

    configs变量为dict,存储配置文件别名和对应的配置文件对象。

    configs = {'default': default,
               'demo01': demo01,
               'demo02': demo02}

    模块存储名为config_name的变量,为配置文件别名。

    # 读取配置文件的名称,在具体的应用中,可以从环境变量、命令行参数等位置获取配置文件名称
    config_name = 'default'

    再声明变量current_config,由get_current_config(config_name)取值,表示当前的配置文件。

    get_current_config会根据配置文件别名,加载不同的配置项。

    current_config = get_current_config(config_name)

    localconfig.py也进行如此配置,甚至可以从config.py中继承。

    唯一不同的是,localconfig.py中,不需要声明config_name和current_config变量。

    配置文件的使用:

    在需要使用配置项的代码中,使用如下代码导入当前的配置文件

    # 读取当前配置项
    # current_config会根据当前的config_name获取到匹配的配置文件对象
    # 如果项目根目录存在localconfig.py,则优先从localconfig.py中读取
    from config import current_config

    获取配置文件中的属性

    # 获取配置文件中的属性
    # 配置文件对象,支持以.(点号)运算符获取对象的属性,也支持以key的形式获取对象的属性
    # 以下两种方式都能获取的配置项
    RABBITMQ_HOST = current_config.RABBIT_HOST
    RABBITMQ_PORT = current_config['RABBITMQ_PORT']

    配置文件支持遍历

    keys = [key for key in current_config]
    assert isinstance(keys, list)
    values = {k: v for k, v in current_config.items()}
    assert isinstance(values, dict)
  • 相关阅读:
    使用ASP.Net WebAPI构建REST服务(一)——简单的示例
    SQL Server 自定义字符串分割函数
    [转]JSP中EL表达式三元运算符的使用
    [转]JSP页面的动态包含和静态包含示例及介绍
    jstl报错:Property 'name' not found on type java.lang.String
    [转]Extjs中的迭代方法
    eclipse mars 4.5.1 自定义工具栏
    [转]Commons IO 官方文档
    【转】eclipse运行 Ant报错Could not find the main class: org.eclipse.ant.internal.launching.remote.InternalAntRunner. Program
    【转】亲测plsql Developer配置免安装oralce客户端步骤
  • 原文地址:https://www.cnblogs.com/blackmatrix/p/8144365.html
Copyright © 2020-2023  润新知