__new__ 在Python中
Python是一种面向对象的编程语言,即Python中的一切都是对象。 Python中有一种特殊的方法,称为魔术方法或 dunder 方法(dunder 在这里的意思是“双下划线”)。 Python中的Dunder或magic方法是方法名称中具有两个前缀和后缀下划线的方法。这些通常用于运算符重载。
魔术方法的几个例子是: __init__
, __add__
, __len__
, __repr__
等。
注意:要了解有关魔术方法的更多信息,请单击此处。
__new__ 方法
每当实例化一个类时,都会调用
__new__
和__init__
方法。 __new__
方法将在创建对象时调用,并调用__init__
方法来初始化对象。在基类object
中,__new__ 方法被定义为需要传递参数cls
的静态方法。 cls
代表需要实例化的类,编译器在实例化的时候自动提供这个参数。句法:
class class_name:
def __new__(cls, *args, **kwargs):
statements
.
.
return super(class_name, cls).__new__(cls, *args, **kwargs)
注意:实例可以在__new__
方法中创建,既可以使用super
函数,也可以直接调用对象的__new__
方法,如果父类是对象。即instance = super(MyClass, cls).__new__(cls, *args, **kwargs)
或instance = object.__new__(cls, *args, **kwargs)
如果类中同时存在 __init__ 方法和 __new__ 方法,则首先执行 __new__ 方法并决定是否使用 __init__ 方法,因为 __new__ 方法可以调用其他类的构造函数,也可以简单地将其他对象作为实例返回这节课。
例子:
# Python program to
# demonstrate __new__
# don't forget the object specified as base
class A(object):
def __new__(cls):
print("Creating instance")
return super(A, cls).__new__(cls)
def __init__(self):
print("Init is called")
A()
输出:
Creating instance
Init is called
上面的例子展示了调用类名时会自动调用 __new__ 方法,而 __new__ 方法每次返回类的实例时都会调用 __init__ 方法,将返回的实例作为self
参数传递给 __init__,因此即使你是将实例保存在全局/静态某处并每次从 __new__ 返回它,然后每次执行此操作时都会调用 __init__。
这意味着如果 __new__ 方法省略了 super,__init__ 方法将不会被执行。让我们看看是不是这样。
# Python program to
# demonstrate __new__
class A(object):
def __new__(cls):
print("Creating instance")
# It is not called
def __init__(self):
print("Init is called")
print(A())
输出:
Creating instance
None
在上面的例子中,可以看到__init__方法没有被调用并且实例化被评估为None
因为构造函数没有返回任何东西。让我们看看如果 __new__ 和 __init__ 方法都返回了一些东西会发生什么。
# Python program to
# demonstrate __new__
class A(object):
# new method returning a string
def __new__(cls):
print("Creating instance")
return "GeeksforGeeks"
class B(object):
# init method returning a string
def __init__(self):
print("Initializing instance")
return "GeeksforGeeks"
print(A())
print(B())
输出:
Creating instance
GeeksforGeeks
Initializing instance
Traceback (most recent call last):
File "/home/62216eb30d3856048eff916fb8d4c32d.py", line 17, in
print(B())
TypeError: __init__() should return None, not 'str'
这个 TypeError 是由调用 __init__ 方法的处理程序引发的,从 __init__ 方法返回任何东西都没有意义,因为它的目的只是改变新创建实例的新状态。
让我们尝试一个示例,其中 __new__ 方法返回不同类的实例。
例子:
# Python program to
# demonstrate __new__ method
# class whose object
# is returned
class GeeksforGeeks(object):
def __str__(self):
return "GeeksforGeeks"
# class returning object
# of different class
class Geek(object):
def __new__(cls):
return GeeksforGeeks()
def __init__(self):
print("Inside init")
print(Geek())
输出:
GeeksforGeeks