我在这里遇到了这个单例实现:http://blog.amir.rachum.com/post/21850841339/implementing-the-singleton-pattern-in-python在第一个回复中。
def singleton(cls):
return cls()
@singleton
class Foo(object):
def bar(self):
pass
if __name__ == '__main__':
print id(Foo)
print id(Foo)
但我不了解内部工作原理,装饰器返回一个类实例,但为什么每次都有相同的实例?
答案 0 :(得分:6)
您可以将该代码重写为
class Foo(object):
pass
Foo = singleton(Foo)
# which is
Foo = Foo()
所以这里类的名称被它的实例化取代。在我看来有点俗气,特别是因为你仍然可以使用Foo.__class__
创建同一类的新对象,并且你正在弄乱命名模式。
答案 1 :(得分:1)
单身人士通过保持内部状态来做到这一点。这里的状态可能是该类的一个实例。装饰者可以是任意的。
看看这个:
http://hairysun.com/downloads/DecoratorHandout.pdf
class Decorator(object):
# in __init__ set up state
def __call__(self, function):
@functools.wraps(function)
def wrapper(*args, **kw): # 1.
print "before func"
result = function(*args, **kw) # 2.
print "after func"
return result
return wrapper # 3.
>>> decorator2 = Decorator()
>>> @decorator2
... def nothing(): pass
装饰器本质上是一个
的功能周围的类(这里是装饰者)可以这样做:
class Singleton(object):
def __init__(self):
self.instance = None
def __call__(self, function):
@functools.wraps(function)
def wrapper(*args, **kw):
if self.instance is None:
self.instance = function(*args, **kw)
return self.instance
return wrapper
我没有运行代码,但我认为这通常是如何工作的。如果没有可用的实例,请创建一个。如果有可用,请不要创建新的 - 返回单个旧的。有人可能想要在生产中使用它之前检查可调用的其他属性。