元类__call__--day26

元类__call__
"""
__call__

调用的意思
在对象被调用时 执行

函数 类

自定义元类 的目的
1.可以通过__call__ 来控制对象的创建过程
2.可用控制类的创建过程

"""
# 自定义一个元类 元类也是一个类 但是需要继承type
class MyMeta(type):

# self 表示要创建对象的那个类(Person) *args是调用Person类时传入的参数
def __call__(self, *args, **kwargs):

print("MyMte中的 call run'")
print(self,*args,**kwargs)
# 下面的三步是固定写法 一个模板 只要你需要控制对象的创建过程 就应该先把模板写出来
# 1.创建空对象
obj = object.__new__(self)
# 2.调用初始化方法
self.__init__(obj,*args,**kwargs)
# self.__init__(obj)
# 3.得到一个完整的对象
return obj

# 修改Person类的元类为MyMeta
class Person(metaclass=MyMeta):

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

def __call__(self, *args, **kwargs):
print("call run...")

#调用Person这个对象时 执行的是 Person的类(type)中__call__ 方法
p = Person("张三疯",80)
print(p)
结果:
# MyMte中的 call run'
# <class '__main__.Person'> 张三疯 80
# <__main__.Person object at 0x0000019A03EBF3C8>

print(p.name)
print(p.age)
结果:
张三疯
80

通过元类控制类的创建过程

# 要控制类的创建过程 只要找到类所属的类 中的__init__即可

class MyMeta(type):

# self 刚建出来的类
# 第二个 类的名字
# 第三个 类的父类们 元组
# 第四个 这个类传进来的名称空间
def __init__(self,class_name,bases,namespace):
print("============================")
#print(self.__dict__)
# 我要控制 类的名字 必须 是大写开头
if not class_name.istitle():
print("类名 必须大写开头...... ")
# 该代码是主动抛出异常
raise TypeError("类名 必须大写开头...... ")
#要空类的创建 必须包含__doc__这个属性
if not self.__doc__:
raise TypeError("类中必须有文档注释.....")

pass

class Student(metaclass=MyMeta): # Student = MyMeta("Student",(object,),{})
"""
这是文档注释 可以通过__doc__来获取
这是一个学生类
"""

# 在类的__init__中可以控制该类对象的创建过程
def __init__(self,name):
print("-----------------------")
print(self.__dict__)
self.name = name

print(Student.__doc__)

posted @ 2018-12-19 19:56  WenChen-0o0  阅读(99)  评论(0编辑  收藏  举报