在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
这工作正常,但我的OCD无法处理我必须导入配置并执行其主类。
我尝试将sys.modules[__name__] = Config()
添加到config.py
的底部,这样我就可以做import config
,但它在reload()
上有:
TypeError: 'NoneType' object is not callable
奇怪的是,我只是期望它抱怨模块命名空间上没有更新这些值,但它似乎是事先破坏 - 只是试图执行reload()
。
我在这里运气不好吗?或者是否有一些神奇的方式我可以用reload()
和单线import config
工作?
当你reload
它不起作用的原因是因为在分配给sys.modules[__name__]
后,模块及其内置函数被垃圾收集并用None
替换。我假设你知道这个,因为你from builtins import *
。但是,导入的内置也将被垃圾收集。
要解决此问题,您可以在reload
中导入内置函数,以便使用不会收集垃圾的版本。
旁注:这是未经测试的,因为我无法重现你的问题here,但我相信它会发生,因为该网站在进口方面可能会不稳定。