在 Python 中使用以下配置单例类:
# -*- coding: utf-8 -*-
from __future__ import unicode_literals, print_function
from builtins import *
import sys
class Config(object):
__instance = None
def __new__(cls):
if cls.__instance is None:
cls.__instance = super(Config, cls).__new__(cls)
cls.__instance.__initialized = False
return cls.__instance
def __init__(self):
print('INIT')
if self.__initialized:
return
self.__initialized = True
self._defaults = {"foo": True, "bar": False}
for k, v in self._defaults.items():
setattr(self, k, v)
def reload(self):
print(self)
if not self._defaults:
return
for k, v in self._defaults.items():
setattr(self, k, v)
我可以编写一个测试来验证属性是否正确设置和更新:
import config; config = config.Config()
print(config)
print(config.foo)
assert(config.foo is True)
config.foo = False
print(config.foo)
assert(config.foo is False)
config.reload()
print(config.foo)
assert(config.foo is True)
输出:
INIT
<config.Config object at 0x10bbf73d0>
True
False
<config.Config object at 0x10bbf73d0>
True
这工作正常,但我的强制症无法处理我必须导入配置并执行其主类。
我尝试添加sys.modules[__name__] = Config()
到 config.py
的底部,这样我就可以做 import config
,但它对 reload()
犹豫不决与:
TypeError: 'NoneType' object is not callable
奇怪的是,我只希望它会提示模块 namespace 上的值没有更新,但它似乎事先就中断了 - 只是试图执行 reload()
.
我是不是运气不好?或者有什么神奇的方法可以让我同时使用 reload()
和一行字import config
?
最佳答案
当您重新加载
时它不起作用的原因是,在分配给sys.modules[__name__]
之后,该模块及其内置函数会被垃圾收集并替换为None
。我假设您知道这一点,因为您 frombuiltins import *
。但是,导入的内置函数也将被垃圾收集。
要解决此问题,您可以在 reload
中导入内置函数,这样您使用的版本就不会被垃圾收集。
旁注:这未经测试,因为我无法重现您的问题 here ,但我相信这种情况会发生,因为该网站在导入方面可能会很不稳定。
关于python - 通过将属性合并/更新到模块的命名空间来加载一次配置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49039628/