说明
《Python 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
在 Python 面向对象编程时,使用 类名() 创建对象的时候,解释器首先会调用 __new__
方法为对象分配空间,从而创建一个类的实例,它是类的构造者(constructor)。
此特殊方法的语法是:
object.__new__(cls[, ...])
object.__new__(cls, *args, **kwargs) # 常用
调用以创建一个 cls 类的新实例。__new__()
是一个静态方法 (因为是特例所以你不需要显式地声明),它会将所请求实例所属的类作为第一个参数。其余的参数会被传递给对象构造器表达式 (对类的调用)。__new__()
的返回值应为新对象实例 (通常是 cls 的实例)。
典型的实现会附带适宜的参数使用 super().__new__(cls[, ...])
,通过超类的 __new__()
方法来创建一个类的新实例,然后根据需要修改新创建的实例再将其返回。
如果在对象构造期间调用 __new__()
并返回 cls 的实例,则新实例的 __init__()
方法将像 __init__(self[, ...])
一样被调用,其中 self 是新实例,其余参数 与传递给对象构造函数的相同。
如果 __new__()
未返回一个 cls 的实例,则新实例的 __init__()
方法就不会被执行。
__new__()
的目的主要是允许不可变类型的子类 (例如 int, str 或 tuple) 定制实例创建过程。它也常会在自定义元类中被重载以便定制类创建过程。
class A(object):
def __init__(self):
print("这是 init 方法")
def __new__(cls):
print("这是 new 方法")
return object.__new__(cls)
A()
'''
这是 new 方法
这是 init 方法
<__main__.A at 0x7f9900d5da50>
'''
主要作用有两个:
Python 解释器获得对象的引用后,将引用作为第一个参数,传递给 __init__
方法。
__init__
区别您可能经常看到 __init__()
但很少使用 __new__()
,这是因为大多数时候您不需要覆盖它。 通常,__init__()
用于初始化新创建的对象,而 __new__()
用于控制对象的创建方式。 我们也可以使用 __new__()
来初始化对象的属性,但逻辑上它应该在 __init__()
中。 然而,__new__()
的一个实际用途可能是限制从一个类创建的对象的数量。
如下:
__new__
至少要有一个参数 cls,代表要实例化的类,此参数在实例化时由 Python 解释器自动提供__new__
必须要有返回值,返回实例化出来的实例,这点在自己实现__new__
时要特别注意,可以 return 父类__new__出来的实例,或者直接是 object 的__new__出来的实例__init__
有一个参数 self,就是这个__new__
返回的实例,__init__
在__new__
的基础上可以完成一些其它初始化的动作,__init__
不需要返回值__init__
方法就是在有原材料的基础上,加工,初始化商品环节假设我们想要一个 Point 类来创建表示点的实例。 这是一个限制类只有两个实例的示例。这里我们从前面的示例中简化了我们的 Point 类。
class Point:
TotalNumberOfPoints = 0 # 新建类变量,点实例数量
MAX_Inst = 2 # 最大实例数限制
def __new__(cls, *args, **kwargs):
print("new executing")
if (cls.TotalNumberOfPoints >= cls.MAX_Inst):
print("ERROR: Cannot create more Point objects!")
return
cls.TotalNumberOfPoints += 1
return super().__new__(cls)
# 默认对象初始化
def __init__(self):
print("init executing")
self.mX = 0.0
self.mY = 0.0
self.mZ = 0.0
@classmethod # 查找类变量的静态方法
def how_many(cls):
"""当前点的数量"""
print(f"We have {cls.TotalNumberOfPoints} points.")
'''
We have 0 points.
new executing
init executing
new executing
init executing
new executing
ERROR: Cannot create more Point objects!
We have 2 points.
'''
https://docs.python.org/zh-cn/3/reference/datamodel.html#object.__new__
更新时间:June 28, 2022, 4:09 p.m. 标签:python 类 实例