python单例类装饰器

时间:2013-01-15 10:57:33

标签: python singleton decorator

我在这里遇到了这个单例实现: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) 

但我不了解内部工作原理,装饰器返回一个类实例,但为什么每次都有相同的实例?

2 个答案:

答案 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

装饰器本质上是一个

的功能
  1. 定义函数
  2. 调用您传入的函数
  3. 返回稍后要调用的新“包装”函数
  4. 周围的类(这里是装饰者)可以这样做:

    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
    

    我没有运行代码,但我认为这通常是如何工作的。如果没有可用的实例,请创建一个。如果有可用,请不要创建新的 - 返回单个旧的。有人可能想要在生产中使用它之前检查可调用的其他属性。