分享
Python中的__new__()方法
输入“/”快速插入内容
Python中的__new__()方法
飞书用户4443
2024年9月12日修改
在Python中,
__new__()
是一个静态方法,它负责创建并返回一个类的新实例。与
__init__()
不同,
__init__()
方法是在实例创建之后调用的,用于初始化实例的属性,而
__new__()
则是在对象创建之前被调用,用来控制对象的创建过程。通常来说,
__new__()
在自定义类时很少使用,除非需要精细控制对象实例的创建行为,或者类是不可变对象(如
tuple
、
str
等),这些类型的对象创建时需要使用
__new__()
。
一.
__new__()
参数和关键点
1.
__new__()
参数
与
__init__()
类似,
__new__()
通常接收与类的构造函数相同的参数,但第一个参数是
cls
,即类本身,而不是
self
。在调用父类的
__new__()
方法时,
cls
作为参数传入。还有其它参数,比如
*args
(位置参数)和
**kwargs
(关键字参数)。
2.
__new__()
特性
(1)
__new__()
是一个类方法,负责创建并返回类的一个实例。
(2)它在
__init__()
之前被调用,并且是负责分配内存空间给新的对象。
(3)
__new__()
通常需要返回一个新实例的对象,通常通过调用父类的
__new__()
来实现。
(4)如果
__new__()
没有返回实例对象,那么
__init__()
将不会被调用。
二.两种方式区别
1.简单示例
通过一个简单示例,展示如何使用
__new__()
方法:
代码块
Python
class MyClass:
def __new__(cls, *args, **kwargs):
print("Calling __new__ method")
instance = super(MyClass, cls).__new__(cls) # 调用父类的__new__方法
return instance
def __init__(self, value):
print("Calling __init__ method")
self.value = value
# 创建类的实例
obj = MyClass(10)
输出结果,如下所示:
代码块
Plain Text
Calling __new__ method
Calling __init__ method
2.super()显隐调用区别
代码
instance = super(MyClass, cls).__new__(cls)
与
instance = super().__new__(cls)
有何区别呢?对于MRO可参考文献[3]。
(1)显示调用
明确地指定了
super()
的第一个参数
MyClass
(当前类),以及
cls
(通常是类本身)。它表示,
super()
会从类的 MRO 顺序中找到
MyClass
的下一个类,并调用该类的
__new__()
方法。
这种方式允许开发者显式地控制从哪个类开始查找父类的
__new__()
方法。它适用于复杂的多继承体系中,当需要精确控制从哪一个类开始解析时,显式传入
MyClass
作为起点。
(2)隐式调用
默认会以当前类和当前对象上下文为基准,自动推导出从当前类的 MRO 中下一个类,并调用该类的
__new__()
方法。它适用于单继承体系中,Python 会自动从当前类的 MRO 中查找下一个类。
代码块
Python
class A:
def __new__(cls):
print("A.__new__ called")
return super(A, cls).__new__(cls)
class B(A):
def __new__(cls):
print("B.__new__ called")
return super(B, cls).__new__(cls)
class C(B):
def __new__(cls):
print("C.__new__ called")
return super().__new__(cls) # 等价于super(C, cls).__new__(cls)
C()