Python单例模式

文章出处: http://py.windrunner.info/design-patterns/singleton.html


装饰器

所有资源资源调用者都是同一个对象,我首先想到的就是装饰器,可以很方便的 给不同的对象增添相同的功能。

Python 官方 wiki 给出了一个非常优雅的实现:

def singleton(cls): instance = cls()
    instance.__call__ = lambda: instance return instance # Sample use @singleton class Highlander: x = 100 # Of course you can have any attributes or methods you like. highlander = Highlander()
another_highlander = Highlander() assert id(highlander) == id(another_highlander)

上面的代码定义了一个 singleton 装饰器,覆盖了类的 __call__ 方法, 该方法会在类创建的时候创建一个类的实例,并在之后类每次的实例化时总是返回这个实例对象。

当然,如果你希望只在需要的时候创建类的实例对象也有别的方法:

def singleton(cls, *args, **kw): instances = {} def _singleton(): if cls not in instances:
            instances[cls] = cls(*args, **kw) return instances[cls] return _singleton @singleton class MyClass(object): a = 1 def __init__(self, x=0): self.x = x

one = MyClass()
two = MyClass() assert id(one) == id(two)

上面的代码中实现了这样一个装饰器:装饰器函数创建的时候会创建一个 instances 字典, 该字典用于保存被装饰器修改过的类的实例,在类初始化的时候首先判断是否存在其实例, 如果存在则直接返回,否则创建一个新的实例保存到 instances 字典中,并返回该实例。 (这段代码出自 cnblogs)

metaclass

我自己对于不是很喜欢装饰器的实现,因为从语言逻辑上来看,我需要的是一个 有单例特性的类而不是为类添加单例限制。于是我又找到了基于 metaclass 的实现:

class Singleton(type): def __init__(cls, name, bases, dict): super(Singleton, cls).__init__(name, bases, dict)
        cls._instance = None def __call__(cls, *args, **kw): if cls._instance is None:
            cls._instance = super(Singleton, cls).__call__(*args, **kw) return cls._instance class MyClass(object): __metaclass__ = Singleton

one = MyClass()
two = MyClass()

上面的代码在类的第一次实例之后将这个个实例作为其类变量保存,在之后调用类的构造函数的时候 都直接返回这个实例对象。

这个解决方案强化了类与其单例之间的内聚性。

参考链接:Creating a singleton in python



你可能感兴趣的:(Python单例模式)