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

# 知识储备: __call__ 方法
class Foo:
def __call__(self, *args, **kwargs):
print(self)
print(args)
print(kwargs)

obj = Foo()

obj(1, 2, 3, a=1, b=2, c=3) # obj.__call__(obj,1, 2, 3, a=1, b=2, c=3)
# 执行结果:
'''
<__main__.Foo object at 0x00000221C0280F98>
(1, 2, 3)
{'a': 1, 'b': 2, 'c': 3}
'''
# 元类内部也应有一个__call__方法,会在调用Foo时触发执行
# Foo(1,2,x=1) #Foo.__call__(Foo,1,2,x=1)


class Mymeta(type):
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)
print(self) # self = Chinese
print(args) # args = ('kingforn',)
print(kwargs) # kwargs = {'age': 18}

# 第一件事:先造一个空对象obj
obj = object.__new__(self)
# 第二件事:初始化obj
self.__init__(obj, *args, **kwargs)
# 第三件事:返回obj
return obj

class Chinese(object, metaclass=Mymeta): # metaclass 元类
"""
这是中国人的类
"""
country = 'china'

def __init__(self, name, age):
self.name = name
self.age = age

def talk(self):
print('%s is talking' % self.name)


obj= Chinese('kingforn', age=18)
print(obj.__dict__) # 结果:{'name': 'kingforn', 'age': 18}
原文地址:https://www.cnblogs.com/kingforn/p/11358425.html