实际上,使用元类来定义单例是一种愚蠢的做法。我不知道这个模式最初是谁提出的,现在已经很普遍了,这是一种过分的杀戮。在
也就是说,只是为了一个快速的答案:当然,重复代码没有意义——更不用说当你连一个参数都不改变的时候——它就是完全相同的代码。只需将其保存在一个文件中并从另一个文件导入,即使您不想为此创建特定的文件。在
现在,元类是Python中一个强大的特性,当人们知道发生了什么时,最好使用它。否则,也会有副作用,最常见的就是无法将您的类与其他具有元类(实际上可能是必需的)的类组合在一起。在
也就是说,这是一个基于decorator的非元类singleton模式:_register = {}
def singleton(cls):
def wrapper(*args, **kw):
if cls not in _register:
instance = cls(*args, **kw)
_register[cls] = instance
return _register[cls]
wrapper.__name__ = cls.__name__
return wrapper
...
@singleton
class Orange:
...
上面的代码是按原样提供的,但是如果使用它,它不会警告有人试图用不同的参数创建第二个实例。它可以更改为不允许参数,或者在重新实例化时引发错误。在
更好的是,decorator模式可以在类声明中创建singleton实例,这与其他模式不同元类。那么,甚至不需要注册,由于该类不可用于尝试生成其不正确的第二个实例(尽管可以这样做type(Orange)()-如果您所在的项目是谁可以破坏代码的上下文:
^{pr2}$
就这样。在@singleton
class Orange:
...
在执行之后,这将把“Orange”作为声明的“Orange”类唯一允许的实例添加到命名空间中。或者,就这样做吧:class Orange:
...
Orange = Orange()
(沃伊拉——你甚至解决了跨模块共享代码的问题——根本不需要额外的代码)