python中的单例

使用__new__

因为一个类每一次实例化的时候,都会走它的__new__方法。所以我们可以使用__new__来控制实例的创建过程,代码如下:

 1 class Single:
 2     instance = None
 3 
 4     def __new__(cls, *args, **kwargs):
 5         if cls.instance:
 6             return cls.instance
 7         cls.instance = object.__new__(cls)
 8         return cls.instance
 9 
10 o1 = Single()
11 o2 = Single()
12 print(o1)  # <__main__.Single object at 0x00000000021EDAC8>
13 print(o2)  # <__main__.Single object at 0x00000000021EDAC8>

使用模块

其实,python的模块就是天然的单例模式,因为模块在第一次导入时,会生成.pyc文件,当第二次导入时,就会直接加载.pyc文件,而不会再次执行模块代码。

1 # 在一个单独的文件定义一个类 并生成它的实例 这里我把它保存到mySingle.py中
2 class Single:
3     pass
4 
5 single = Single()
1 from SingleFile import single
2 # 后续在其它文件直接导入使用该对象 该对象便是单例的
3 obj = single

使用装饰器

我们知道,装饰器可以动态的修改一个类或函数的功能。这里,我们也可以使用装饰器来装饰某个类,使其只能生成一个实例:

 1 def singleton(cls):
 2     instances = {}
 3     def getinstance(*args,**kwargs):
 4         if cls not in instances:
 5             instances[cls] = cls(*args,**kwargs)
 6         return instances[cls]
 7     return getinstance
 8 
 9 @singleton
10 class MyClass:
11     a = 1
12 
13 c1 = MyClass()
14 c2 = MyClass()
15 print(c1 == c2) # True

使用元类

元类(metaclass)可以控制类的创建过程,它主要做三件事:拦截类的创建、修改类的定义、返回修改后的类。使用元类实现单例模式的代码如下:

 1 class Singleton(type):
 2     _instances = {}
 3     def __call__(cls, *args, **kwargs):
 4         if cls not in cls._instances:
 5             cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
 6         return cls._instances[cls]
 7 
 8 # Python2
 9 # class MyClass(object):
10 #     __metaclass__ = Singleton
11 
12 # Python3
13 class MyClass(metaclass=Singleton):
14    pass
15 
16 a=MyClass()
17 b=MyClass()
18 print(a==b)
19 print(a is b)
20 print(id(a),id(b))
posted @ 2018-07-18 15:41  zze  阅读(198)  评论(0编辑  收藏  举报