元类之__new__
元类之_new_
__new__和__init__的区别
__new__ 创建空对象
__init__ 初始化空对象
object.__new__(People): # 生成Person类的对象(空的)
type.__new__(cls,name,bases,dic) # 生成具有name,bases,dic这个类对象,里面有东西
#元类中
__init__: 控制类的产生,在__new__之后
__call__: 对着对象的产生
__new__: 控制类产生最根上,其实本质最根上也不是它,是type的__call__,但是我们控制不了了
class Mydeta(type):
def __new__(cls,name,bases,dic):
# 产生空对象(空类),在这里生成的并不是空类,是有name,bases,dic这些东西的类。
# 如何完成类的的初始化,并且将name,bases,dic放进去呢
# return type.__new__(cls,name,base,dic),即可。
# 如何将类的属性封装在字典中隔开存储起来再返回出去呢?这样做
# 只需改变dic,即创建类的内存空间,将不同的属性封装在新字典里即可。
dic2 = {'attr':{}}
for k,v in dic.items():
if not k.startswith('__'): # 过滤掉内置属性,只留下用户自定义的属性。
dic2['attr'][k] = v
print(dic2) # {'attr': {'school': 'oldboy', 'age': 10}}
return return type.__new__(cls,name,base,dic2) # 返回新的类
class Person(metaclass=Mymeta):
# Person=Mymeta(name,bases,dic)
# 调用type的__call__,内部调用了Mymeta.__new__,又调用Mymeta的__init__
school='oldboy'
age=10
def __init__(self,name,age):
self.name=name
self.age=age
print(People.attr['school']) # oldboy
print(People.__dict__)
# {'attr': {'school': 'oldboy', 'age': 10}, '__module__': '__main__', '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None}