實現目標:python
最新的代碼能夠參考 https://github.com/blackmatrix7/matrix-toolkit/blob/master/toolkit/config.pygit
#!/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
使用示例:github
在項目根目錄建立 config.py 和 localconfig.py。測試
localconfig.py能夠不建立(若是不須要本地配置文件的話),若是建立localconfig.py,須要在.gitignore中,將localconfig.py排除掉。spa
當項目根目錄同時存在config.py 和 localconfig.py時,優先讀取localconfig.py的配置項。命令行
config.py 完整代碼:code
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模塊中:orm
每套配置都爲獨立的類,繼承自BaseConfig,並將其實例化。對象
若有必要,在多套配置文件類中,能夠互相繼承。好比DemoConfig01繼承自BaseDemoConfig。blog
在配置文件類的繼承中,比較特別的是須要經過其餘屬性參與運算獲取的配置項,須要使用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)