Python_加载配置package目录下所有py文件中大写的变量

加载配置目录下所有py文件中以大写字母定义的常量,不允许从外部设置常量配置。

import sys
import pkgutil


class _Settings(object):
    """ 配置读取接口 """

    def __init__(self):
        self.settings_dir = "conf"  # 配置目录,填目录路径id
        self.keys = set()
        self._load()

    def _load(self):
        """ 加载配置 """
        module_names = self._get_module_names()
        for module_name in module_names:
            __import__(module_name)
            mod = sys.modules[module_name]
            self._load_setting_from_module(mod)
        self.__loaded = True    # 加载完成标识,加载完后,不允许从外部再设置配置

    def _get_module_names(self):
        """ 获取配置目录下所有模块"""
        module_names = [self.settings_dir]
        mod = __import__(self.settings_dir, fromlist=[""])
        for file_finder, module_name, is_pkg in pkgutil.walk_packages(mod.__path__, mod.__name__ + "."):
            module_names.append(module_name)
        return module_names

    def _load_setting_from_module(self, module):
        """ 从模块中加载配置 """
        for name in dir(module):
            if name.startswith('__'):
                continue
            if name.isupper():
                self.keys.add(name)
                setattr(self, name, getattr(module, name))

    def get(self, name, default_value=None):
        """ 获取配置值,未获取到则返回默认值,因为重写了__getattr__方法,当获取不存在的属性时不会报错 """
        v = getattr(self, name)
        if v is not None:
            return v
        else:
            return default_value

    def __setattr__(self, name, value):
        if self.get(name):
            raise RuntimeError("变量 %s 被多次定义!!" % name)
        else:
            if self.__loaded is True:
                raise RuntimeError("不允许动态设置变量: " + name)
            super(_Settings, self).__setattr__(name, value)

    def __getattr__(self, item):
        """ 当获取的属性值未被定义时返回None,而不报错 """
        return


settings = _Settings()

代码及配置目录结构

 获取配置常量

from frame_lib.conf import settings

# 查看定义的常量
print(settings.keys)

# 获取常量V1
v1 = settings.get("V1")
print(v1)

# 获取常量V2
v2 = settings.V2
print(v2)

# 不允许从外部设置常量
setattr(settings, "YY", "123")

执行结果

 

posted @ 2022-03-13 14:59  码上测  阅读(156)  评论(0编辑  收藏  举报