一、使用__new__方法可以实现单例模式:
class SingleTon(object): def __new__(cls, *args, **kw): if not hasattr(cls, 'instance'): cls.instance = object.__new__(cls, *args, **kw) return cls.instance class TestClass(SingleTon): def __init__(self, num): self.num = num test1 = TestClass(1) test2 = TestClass(2) print test1.num, test2.num print id(test1), id(test2)
TestClass类实例化时,因为自身的__new__方法没有重写,默认会调用其父类,也就是SingleTon的__new__方法。而SingleTon的__new__方法重写为仅当自身没有instance属性时才会返回一个类实例,从而确保了仅生成1个实例。
上述代码运行后的结果:
2 2 48477016 48477016
两个实例的id相同,说明是同一个实例。但是其num值为2,是因为第二次实例化test2时,在__init__中将其num覆盖成了2。
二、使用装饰器实现单例模式:
from functools import wraps def SingleTon(cls): instances = {} @wraps(cls) def getinstance(*args, **kwargs): if cls not in instances: instances[cls] = cls(*args, **kwargs) return instances[cls] return getinstance
这样就能通过@SingleTon来对自定义的类进行装饰,从而实现单例模式。
@SingleTon class TestClass(object): def __init__(self, num): self.num = num test1 = TestClass(1) test2 = TestClass(2) print test1.num, test2.num print id(test1), id(test2)
输出为:
1 1 48214760 48214760
不同于方法一,这里输出的num值为1。