Python Singleton;__init__ __call__;__metaclass__;Python 单例介绍

1 首先网上有很多实现方式,而且stackflow里面有大神详细介绍了各种实现。自己google吧,就不贴URL了。


我这里简述原理,放个简单demo帮助理解。

  1 class Singleton(type):                                                                                               
  2     def __init__(self, name, bases, dic):
  3         print ".... Singleton.init ...."
  4         super(Singleton, self).__init__(name, bases, dic)
  5         self.instance = None
  6 
  7     def __call__(self, *args, **kwargs):
  8         print ".... Singleton.call ...."
  9         if self.instance is None:
 10             self.instance = super(Singleton, self).__call__(*args, **kwargs)
 11         return self.instance
 12 
 13 print "====================== 1 ======================="
 14 class test:
 15     __metaclass__ = Singleton #call Singleton.__init__
 16     def __init__(self):
 17         print "test.init ..."
 18     def __call__(self):
 19         print "test.call ..."
 20 
 21 class test2:
 22     __metaclass__ = Singleton #call Singleton.__init__
 23     def __init__(self):
 24         print "test2.init ..."
 25     def __call__(self):
 26         print "test2.call ..."
 27 
 28 print "====================== 2 ======================="
 29 a = test() #call Singleton.__call__
 30 b = test2() #call sSngleton.__call__
 31 
 32 print "====================== 3 ======================="
 33 a1 = test()
 34 b1 = test2()
 35 print id(a),id(a1),id(b),id(b1)
 36 print "====================== 4 ======================="
 37 a1()
 38 b1()
 39 
 40 print "====================== 5 ======================="
 41 a.c = 100
 42 b.c = 111
 43 print a1.c
 44 print b1.c

输出结果:

1  bash-3.2$ python test.py 
2  ====================== 1 =======================
3  .... Singleton.init ....
4  .... Singleton.init ....
5  ====================== 2 =======================
6  .... Singleton.call ....
7  test.init ...
8  .... Singleton.call ....
9  test2.init ...
10 ====================== 3 =======================
11 .... Singleton.call ....
12 .... Singleton.call ....
13 4476624848 4476624848 4476670096 4476670096
14 ====================== 4 =======================
15 test.call ...
16 test2.call ...
17 ====================== 5 =======================
18 100
19 111




demo中建了2个单例类,test,test2。都是通过__metaclass__ = Singleton的方式。

测试结果:

通过测试输出可以看出,id(a) = id(a1),id(b)=id(b1); 而且创建一个c attribute给a,a1同时也会得到一个一模一样的c,包括c的值。 说明单例OK。


原理:

这里单例是用__metaclass__方式实现。__metaclass__的意思就是class的class。

所以一旦设定test和test2的__metaclass__ == Singleton,就会利用Singleton类的实例来作为test,test2的类。(稍微有点拗口)


请注意line 14和line 22,这2个地方对应输出结果里面line 2,line3的打印。说明:我们一旦设定test,test2的__metaclass__ = Singleton了,Singleton就立刻__init__ ,而且对于每个单例类(这里的test或test2)只在定义的时候做一次。


后面我们实例话test,test2的时候:a = test(),b=test2();则系统会调用Singleton的__call__;实例化几次test,test2,就调用几次Singleton的__call__ 。 所以,我们只要在Singleton的__call__里面做单例的实现即可。


具体实现方式很简单,看源码即可。


补充一下:

test类的__init__ 函数对应 a=test()调用

__call__函数对应 a()


你可能感兴趣的:(Singleton,python,__init__,__call__)