自定义元类控制类的实例化行为(二)

# 单例模式:
# 实现方式一:
class Mysql:
__instance=None # __instance=obj

def __init__(self):
self.host = '127.0.0.1'
self.port = 3306

@classmethod
def singleton(cls):
if not cls.__instance: # 空值是真,执行下面代码 ;有值是假直接返回
obj = Mysql()
cls.__instance = obj # __instance=obj
return cls.__instance

def conn(self):
pass


obj1 = Mysql.singleton()
obj2 = Mysql.singleton()
obj3 = Mysql.singleton()
print(obj1 is obj2) # True
print(obj1 is obj3) # True
print(obj1, obj2, obj3)
'''执行结果:
<__main__.Mysql object at 0x000001F87E050F98> <__main__.Mysql object at 0x000001F87E050F98> <__main__.Mysql object at 0x000001F87E050F98>
'''

# 实现方式二:元类的方式


class Mymeta(type):
__instance = None
def __init__(self, class_name, class_bases, class_dic):
if not class_name.istitle(): # class_name 首字母不是大写就报类型错误
raise TypeError('类型错误')
if '__doc__' not in class_dic or not class_dic['__doc__'].strip():
raise TypeError('必需要有注释且不能为空')

super(Mymeta, self).__init__(class_name, class_bases, class_dic)

def __call__(self, *args, **kwargs): # obj = Chinese('kingforn',age=18)

if not self.__instance:
obj = object.__new__(self)
self.__init__(obj, *args, **kwargs)
self.__instance = obj

return self.__instance


class Mysql(object, metaclass=Mymeta):
'''元类控制实例化'''
def __init__(self):
self.host = '127.0.0.1'
self.port = 3306

def conn(self):
pass


obj1 = Mysql()
obj2 = Mysql()
obj3 = Mysql()
print(obj1 is obj2) # True
print(obj1 is obj3) # True
print(obj1, obj2, obj3)
'''结果:
<__main__.Mysql object at 0x0000029605CB6C18> <__main__.Mysql object at 0x0000029605CB6C18> <__main__.Mysql object at 0x0000029605CB6C18>
'''
原文地址:https://www.cnblogs.com/kingforn/p/11360172.html