假设您想像 Michael Aaron Safyan 建议的那样将模块用作单例,即使该模块不是由主代码导入,您也可以通过执行以下操作(在主代码或它确实导入的模块中)使其工作直接或间接)。它所做的是将一个instance
类属性初始化为一个,然后用sys.modules
创建的实例替换模块对象:
class _MyClass(object):
def foo(self):
print 'foo()'
_MyClass.instance = _MyClass()
import sys
_ref = sys.modules[__name__] # Reference to current module so it's not deleted
sys.modules[__name__] = _MyClass.instance
当只有一个(注册表)有意义时,我发现单例是一种实现事物“寄存器”的有用方法——例如类工厂的一组类、一组常量或一组配置信息. 在许多情况下,只需一个普通的 Python 模块就可以了,因为默认情况下,它们实际上已经是单例,因为那些已经加载的模块会缓存在sys.modules
字典中。
然而,有时,类实例更可取,因为它们可以传递构造参数并具有属性——内置模块对象没有也不能拥有的东西。可以使用上面显示的技巧来解决此类限制,该技巧有效地将自定义类实例转换为模块对象。
使用类实例作为模块对象的想法来自Alex Martelli的ActiveState配方,名为Python 中的常量。