前言
在学习__new__(cls,[ *args])
方法之前,我们知道,当实例化一个对象时,首先调用的是 __init__()
方法初始化对象,但在我们学习了了__new__()
魔法方法后,就会发现我们这种认知是错误的。
__new__(cls,[ *args])
•__new__
是实例化对象调用的第一个方法(不是__init__
方法)•它的第一个参数是这个类(cls
),其他参数直接传递给__init__
方法.•__new__
方法返回一个实例对象,如果没有返回实例对象,则__init__
方法不会调用. 绝大多部分情况下,我们不需要重载__new__
方法,但当继承一个不可变的类如str
,int
类等,我们可以通过__new__
方法来自定这些类的实例化过程。
如一个类继承str
:
>>> class str_cls(str):
... def __init__(self,string):
... self = string
...
>>> a = str_cls('aaa')
>>> print(a)
aaa
self = string
表示实例初始化对象时,这个对象所指向的就是传入的参数。那现在想实现把实例对象时的入参变成大写,如下所示:
>>> a = str_cls('aaa')
>>> print(a)
AAA
如果我们只通过修改__init__
方法是实现不了该功能的:
...
self = string.upper()
...
我们必须通过重载__new__
方法来实现:
>>> class str_cls(str):
... def __new__(cls,string):
... string = string.upper()
... return super().__new__(cls,string)
...
>>> a = str_cls('aaa')
>>> print(a)
AAA
对于这些不可变的对象,我们只有通过__new__
方法处理,才能得到我们想要的结果。
__new__
和 __init_
相配合,才是真正的类构造器。