Python----面向对象---自定义元类控制类的实例化行为的应用

一、单例模式

 1 class Mysql:
 2     def __init__(self):
 3         self.host = '127.0.0.1'
 4         self.port = 3306
 5 
 6 
 7 obj1 = Mysql()
 8 obj2 = Mysql()
 9 
10 print(obj1)
11 print(obj2)
12 
13 结果为:
14 
15 <__main__.Mysql object at 0x0000021CBF4DB588>
16 <__main__.Mysql object at 0x0000021CBF4DB160>

可以看出,两个对象的内存地址不一样,但是对象的属性是一样的,能不能只实例化一次,然后其它对象都引用它,就像a =1 b =1 ,,我们发现,他们指向的是同一块内存地址,答案是可以的,这就是单例模式,

 1 class Mysql:
 2     __instance = None
 3 
 4     def __init__(self):
 5         self.host = '127.0.0.1'
 6         self.port = 3306
 7 
 8     @classmethod
 9     def singleton(cls):
10         print(cls)
11         if not cls.__instance:
12             obj = cls()
13             cls.__instance = obj
14         return cls.__instance
15 
16     def conn(self):
17         pass
18 
19     def execute(self):
20         pass
21 
22 
23 # obj1 = Mysql()
24 # obj2 = Mysql()
25 #
26 # print(obj1)
27 # print(obj2)
28 
29 obj1 = Mysql.singleton()
30 obj2 = Mysql.singleton()
31 obj3 = Mysql.singleton()
32 
33 print(obj1 is obj2 is obj3)
34 
35 结果为;
36 
37 <class '__main__.Mysql'>
38 <class '__main__.Mysql'>
39 <class '__main__.Mysql'>
40 True

以上就是实现单例模式的一种方式,class,下面介绍第二种方式,通过元类实现单例模式

实现方式2: 元类的方式

代码如下:

 1 class Mymeta(type):
 2     def __init__(cls, class_name, class_bases, class_dic):
 3 
 4         if not class_name.istitle():
 5             raise TypeError('类名的首字母必须大写')
 6 
 7         if '__doc__' not in class_dic or not class_dic['__doc__'].strip():
 8             raise TypeError('必须有注释,且注释不能为空')
 9 
10         super(Mymeta, cls).__init__(class_name, class_bases, class_dic)
11         cls.__instance = None
12 
13     def __call__(cls, *args, **kwargs):
14         if not cls.__instance:
15             obj = object.__new__(cls)
16             cls.__init__(obj)
17             cls.__instance = obj
18 
19         return cls.__instance
20 
21 
22 class Mysql(object, metaclass=Mymeta):
23     '''
24     xxxx
25     '''
26     def __init__(self):
27         self.host = '127.0.0.1'
28         self.port = 3306
29 
30     def conn(self):
31         pass
32 
33     def execute(self):
34         pass
35 
36 
37 obj1 = Mysql()
38 obj2 = Mysql()
39 obj3 = Mysql()
40 
41 print(obj1 is obj2 is obj3)
42 
43 结果为:
44 
45 True

结果为True,实现了单例模式

原文地址:https://www.cnblogs.com/xudachen/p/8666833.html