面向对象之魔术方法__init__()和__new__()
魔术方法:
魔术方法就是一个类/对象中的方法,和普通方法唯一的不同时,普通方法需要调用!而魔术方法是在特定时刻自动触发。
1.__init__
初始化魔术方法
触发时机:初始化对象时触发(不是实例化触发,但是和实例化在一个操作中)
参数:至少有一个self,接收对象
返回值:无
作用:初始化对象的成员
注意:使用该方式初始化的成员都是直接写入对象当中,类中无法具有
2.__new__
实例化魔术方法
触发时机: 在实例化时触发
参数:至少一个cls 接收当前类
返回值:必须返回一个对象实例
作用:实例化对象
注意:实例化对象是Object类底层实现,其他类继承了Object的__new__才能够实现实例化对象。
没事别碰这个魔术方法,先触发__new__才会触发__init__
class Person: def __init__(self, name): print("---->init方法") self.name = name def __new__(cls, *args, **kwargs): print("---->new") p = Person('Jack') print(p) print(p.name)
可以看到__init__()方法没有执行,这是什么原因?
__init__()依赖__new__(),原来系统里面有__new__()方法的,可以帮助执行__init__()方法,现在我们自己实现了一个__new__()方法,这样就把系统的__new__()方法覆盖了
也就是说,当实例化时,p = Person(),先进入到__new__()方法中
class Person: def __init__(self): print("---->init方法") # self.name = name def __new__(cls, *args, **kwargs): print("---->new") return object.__new__(cls, *args, **kwargs) p = Person()
__new__()的真正作用:向内存要空间--->地址
class Person: # 初始化(构造方法),创建对象是自动执行 def __init__(self, name): print("---->init方法") self.name = name def __new__(cls, name): print("---->new") # 不知道new方法是做什么的,那么就直接返回父类的new方法 return super(Person, cls).__new__(cls) p = Person('Jack')
总之:
因此可以这么描述__new__()和__init__()的区别,在新式类中__new__()才是真正的实例化方法,为类提供外壳制造出实例框架,然后调用该框架内的构造方法__init__()使其丰满。
如果以建房子做比喻,__new__()方法负责开发地皮,打下地基,并将原料存放在工地。而__init__()方法负责从工地取材料建造出地皮开发招标书中规定的大楼,__init__()负责大楼的细节设计,建造,装修使其可交付给客户。