【发布时间】:2018-06-29 06:53:37
【问题描述】:
我正在尝试为 python 创建一个 yaml 驱动的配置模块,该模块既可以从平面 yaml 文件加载,也可以选择从 sys.argv 加载参数。它还将加载的属性保存到一个局部变量中(这很丑陋,但每次引用 config 时解析 yaml 文件仍然更可取)。
我有这个工作,但我必须导入它的方式似乎过头了,而且不是很pythonic。有没有更优雅的方式来构造它,以便:
- 我可以使用单个导入语句
- 我可以确保配置的加载次数(在使用它的不同模块中)不会超过绝对必要的次数
结构:
/app
/__init__.py
/__main__.py # calls __init__.py
/config.yaml
/applib
/__init__.py
/__config_loader.py
在应用程序的主 __init__.py 中,我像这样加载配置:
from applib.config_loader import Config; config = Config()
# ^ ew!
在config_loader.py,我有:
import argparse
import yaml
class Config:
_config = None
@property
def config(self):
if self._config is not None:
print('Using what we already loaded')
return self._config or Config()
def __init__(self):
if self._config is None:
print('Loading config')
with open(os.path.join(os.path.dirname(os.path.dirname(__file__)), 'config.yaml')) as yaml_config_file:
self._config = yaml.load(yaml_config_file)
parser = argparse.ArgumentParser(description = 'MyApp')
parser.add_argument('--an_arg')
args = parser.parse_args()
def __getattr__(self, name):
return self._config[name] or None
当然不是让它工作的最漂亮的方式,而且似乎我无法理解在 python 中做事的新旧方式使情况过于复杂。
我希望能够像这样加载它:
from applib.config_loader import config
print(config['an_arg'])
【问题讨论】:
-
"但是每次引用config时还是解析yaml文件更好"为什么每次引用
config都要解析yaml文件? -
从我的测试来看,每次引用
config时都会调用__init__,因此每次都会解析yaml文件。也许我错了? -
为什么不在 applib.config 文件的末尾添加行
config = Config()呢?然后from applib.config import config将按照您的意愿工作。 -
顺便说一句,变量
Config._config没有被构造函数Config.__init__中的语句self._config = [something]初始化。这将为该实例创建一个名为“_config”的新 member 变量,但不会影响名为“_config”的 class 变量。除非您执行语句Config._config = [something],否则不会设置类变量。 -
是的,@PaulCornelius 你完全正确。至少我想多了是对的???把它扔进去,我会接受的。
标签: python python-2.7 python-module