new() 方法主要存在于Python2的新式类和Python3中。它是负责创建类实例的静态方法。

当Python实例化一个对象时,首先调用__new__()方法构造一个类的实例,并为其分配对应类型的内存空间,该实例的内存地址就是它的唯一标识符。然后再调用__init__()方法对实例进行初始化,通常是对该实例的属性进行初始化。

以下用几个实例来说明:

实例1:先调用__new__()方法再调用__init__()方法

class Person(object):
    
    def __new__(cls):
        print("__new__ called")
        return super().__new__(cls)
    
    def __init__(self):
        print("__init__ called")
		  
a = Person()
		

结果:

__new__ called
__init__ called

实例2:new()方法构造一个类实例,并将该实例传递给自身的__init__()方法,即__init__()方法的self参数。

class Person(object):
    
    def __new__(cls):
        print("__new__ called")
        instance = super().__new__(cls)
        print(type(instance))
        print(instance)
        print(id(instance))
        return instance
    
    def __init__(self):
        print("__init__ called")
        print(id(self))

b = Person()

结果:

__new__ called
<class '__main__.Person'>
<__main__.Person object at 0x1093c1580>
4449899904
__init__ called
4449899904

实例3:如果__new__()方法不返回任何实例的话,init()方法将不会被调用。

class Person(object):
    
    def __new__(cls):
        print("__new__ called")

    def __init__(self):
        print("__init__ called")

c = Person()

结果:

__new__ called

实例4:如果__new__()方法返回一个其他类的实例的话,那它自身的__init__()方法将不会被调用。而且,new()方法将会初始化一个其他类的对象。

class Animal(object):

    def __init__(self):
        pass

class Person(object):
    
    def __new__(cls):
        print("__new__ called")
        return Animal()

    def __init__(self):
        print("__init__ called")

d = Person()
print(type(d))
print(d)

结果:

__new__ called
<class '__main__.Animal'>
<__main__.Animal object at 0x10fea3550>

实例5:如果重写__new__()方法时,除了cls参数外不再设置其他参数的话,将无法用__init__()方法来设置初始化参数。

class Person(object):
    
    def __new__(cls):
        print("__new__ called")
        instance = super().__new__(cls)
        return instance
    
    def __init__(self, name):
        print("__init__ called")
        self.name = name

e = Person("Eric")
print(e.name)

结果:

Traceback (most recent call last):
  File "example.py", line 102, in <module>
    e = Person("Eric")
TypeError: __new__() takes 1 positional argument but 2 were given

实例6:在重写__new__()方法时,需要在参数中加入*args,**kwargs,或者显式地加入对应的参数,才能通过__init__()方法初始化参数。

class Person(object):
    
    def __new__(cls, *args,**kwargs):  # Or def __new__(cls, name)
        print("__new__ called")
        instance = super().__new__(cls)
        return instance
    
    def __init__(self, name):
        print("__init__ called")
        self.name = name

e = Person("Eric")
print(e.name)

结果:

__new__ called
__init__ called
Eric
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐