Python单例类装饰器

3

3
单例模式是一种设计模式,它限制了一个类的实例化只能创建一个对象。当系统中需要协调操作的唯一对象时非常有用... 比如日志记录,因为你希望在整个应用程序中记录到同一个文件中。 - avasal
我知道单例模式是什么,但我不明白为什么这个特定的实现像一个单例。 - Alexander Pope
4
请注意,这并不是真正的单例模式,因为用户不会实例化该类。这只是将类替换为类的实例,然后用户将该名称用作实例。 - Ned Batchelder
2个回答

7
你可以将代码重写为
class Foo(object):
    pass

Foo = singleton(Foo)
# which is
Foo = Foo()

因此,这里类的名称被其实例化所取代。据我看来,有点俗套,特别是你仍然可以使用Foo.__class__创建相同类的新对象,并且你会破坏命名模式。


在Python中为单例模式创建类是完全没用的。这可能是从Java或其他C++导入的最糟糕的反模式。只需在模块级别创建Foo()的一个实例,然后将其称为“singleton”: singleton = Foo()……就这样! - Christophe

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. 返回新的'包装'函数以供以后调用

周围的类(在这里:装饰器)可以做这样的事情:

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

我没有运行这段代码,但我认为这大致是它的工作原理。如果没有可用的实例,则创建一个。如果有一个可用的实例,则不要创建新的 - 而是返回单个旧实例。在生产中使用此方法之前,可能需要检查可调用对象的其他属性。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接