- __new__方法的作用是创建并返回一个实例对象
- 如果当前类中没有定义__new__方法,Python默认是调用该类的直接父类的__new__()方法来构造该类的实例,如果该类的父类也没有重写__new__(),那么将一直按此规矩追溯至object的__new__()方法
- __new__方法是一个类实例化时调用的第一个方法,调用后返回实例对象再交给__init___方法进行初始化
- __new__决定是否要使用__init__方法,如果__new__没有返回实例对象,则__init__不会调用进行初始化
- __new__必须有一个参数cls,代表要实例化的类,如果__new__只调用了一次,就会得到一个对象
- 如果要得到当前类的实例,应该在当前类中的__new__方法中调用当前类的父类的__new__方法
- __init__方法的参数self其实就是__new__方法返回的实例对象,在这个__init__方法中还可以对这个实例进行其他的操作,比如添加一些属性等
实例1:
先调用__new__再调用__init__
class Person:
# 在当前类的__new__方法中调用父类的__new__,重写并得到当前类的实例
def __new__(cls, *args, **kwargs):
print("先调用__new__方法")
return super().__new__(cls)
def __init__(self):
print("后调用__init__方法")
p = Person()
实例2:
__new__方法构造一个当前类的实例,并将该实例传递给当前类的__init__方法,即传给__init__的self参数
class Person:
# 在本类的__new__方法中调用父类的__new__方法并返回
def __new__(cls, *args, **kwargs):
return super().__new__(cls)
# 将返回的对象传给self初始化
def __init__(self):
print("实例对象初始化完成")
p = Person()
实例3:
如果__new__方法不返回任何实例对象,那么__init__方法不被调用
class Person:
# 不返回实例对象
def __new__(cls, *args, **kwargs):
super().__new__(cls)
def __init__(self):
print("实例对象初始化完成")
p = Person()
实例4:
如果__new__方法返回一个其它类的实例,那么它自身的__init__方法不会被调用,而且__new__方法会初始化一个其它类的对象
class Animal:
def __init__(self):
pass
class Person:
# 返回Animal类的实例
def __new__(cls, *args, **kwargs):
print("调用__new__方法,返回Animal的实例")
return Animal()
def __init__(self):
print("__init__不会被调用")
p = Person() # 调用__new__方法,返回Animal的实例
print(type(p)) # <class '__main__.Animal'>
实例5:
如果在当前类重写__new__方法时,除了cls参数外不再设置其它参数,那么__init__方法初始化时除了self就无法设置其它参数
class Person:
def __new__(cls):
return super().__new__(cls)
def __init__(self,name):
self.name = name
p = Person("张三")
print(p.name)
输出:
Traceback (most recent call last):
File "/Users/fang_doge/PycharmProjects/test2.py", line 8, in <module>
p = Person("张三")
TypeError: __new__() takes 1 positional argument but 2 were given
实例6:
重写__new__方法时,需要在参数中传入*args,**kwargs,或者显式地传入对应的参数,那么__init__方法初始化时才能设置其它参数
class Person:
def __new__(cls, *args,**kwargs):
return super().__new__(cls)
def __init__(self,name,age):
self.name = name
self.age = age
p = Person("张三",22)
print(p.name)
print(p.age)