__new__方法和call加init的关系

赠送元类

object.__new__

class Person():
    def __init__(self, name, age):
        print('__init__')
        self.name = name
        self.age = age
    def __new__(cls, *args, **kwargs):
        print('__new__')
        #规范步骤 首先调元类的__call__, 再调Person类的__new__,最后调__init__返回出去
        # 生成一个Person类的空对象
        return object.__new__(cls)
        

p = Person('hys', 16)
print(p)	# 这里是个None, 空对象

# object.__new__ 传哪个类,就得到哪个类的空对象
# p = object.__new__(Person)
# print(p)

__new____init__的区别 : __new__就是产生一个空对象, __init__来完成初始化

__new__ 创建一个空对象 必须return 返回一个对象;不然后续的操作都走不了了

__init__ 初始化空对象

在元类里面如何写(深层次)

object.__new__(Person) 生成的Person类的对象 空的 object产生类的对象

type.__new__(cls, name, bases, dic) 生了cls这个对象,里面有东西 type产生类对象

class My_class(type):
    def __init__(self, name, bases, dic):
        print('My_class的__init__')
        
    def __new__(cls, name, bases, dic):
        print('My_class的__new__')
        # 产生空对象(空类),但其实这里面生成的并不是空类,而是有数据的类了
        # 如何完成类的初始化,并且把name, bases, dic这三个参数放入
        return type.__new__(cls, name, bases, dic)

# Person=My_class(name,bases,dic)  调用type的__call__,内部又调用了My_class.__new__,最后调用了My_class的__init__
class Person(metaclass=My_class):
    def __init__(self, name, age):
        self.name = name
        self.age = age
       
# 这里实例化产生对象时,先调用Person类的元类My_class的__call__
p = Person('hys', 16)

元类的调用流程Person=My_class(name,bases,dic) 调用type的__call__,内部又调用了My_class.__new__,最后调用了My_class的__init__

总结:

object.__new__(Person) 生成的Person类的对象 空的 object产生类的对象

type.__new__(cls, name, bases, dic) 生了cls这个对象,里面有东西 type产生类对象

__new__: 控制类产生最根上, 其实本质最根上也不是它,是type的__call__, 但是我们控制不了了

__init__: 控制类的产生, 在__new__之后

__call__: 对着对象的产生

实例化产生类

方法一:

方法二:

image-20231026143012891

实例化产生对象

image-20231026115601257

小结

当你实例化产生类对象时

image-20231026141737153

当你实例化产生对象时

image-20231026141808944

概括:在两种情况下,元类通常负责创建类对象,而类的 __init__ 方法负责初始化对象。类对象是模板,实例对象是基于模板创建的具体实体。

posted @ 2023-10-30 11:22  hanyingshuo  阅读(13)  评论(0)    收藏  举报