inint与 new 方法

__init____new__ 方法

__new____init__参数的不同

__new__所接收的第一个参数是cls,而__init__所接收的第一个参数是self。这是因为当我们调用__new__的时候,该类的实例还并不存在(也就是self所引用的对象还不存在),所以需要接收一个类作为参数,从而产生一个实例。而当我们调用__init__的时候,实例已经存在,因此__init__接受self作为第一个参数并对该实例进行必要的初始化操作。这也意味着__init__是在__new__之后被调用的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class newStyleClass(object): 
# In Python2, we need to specify the object as the base.
# In Python3 it's default.

def __new__(cls):
print("__new__ is called")
return super(newStyleClass, cls).__new__(cls)

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

n=newStyleClass()
print(n)

结果如下:

1
2
3
4
__new__ is called
__init__ is called
self is: <__main__.newStyleClass at 0x109290890>
<__main__.newStyleClass at 0x109290890>

创建类实例并初始化的过程中__new____init__被调用的顺序也能从上面代码的输出结果中看出:__new__函数首先被调用,构造了一个newStyleClass的实例,接着__init__函数在__new__函数返回一个实例的时候被调用,并且这个实例作为self参数被传入了__init__函数。****

这里需要注意的是,如果__new__函数返回一个已经存在的实例(不论是哪个类的),__init__不会被调用。如下面代码所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
obj = 12 
# obj can be an object from any class, even object.__new__(object)

class returnExistedObj(object):
def __new__(cls):
print("__new__ is called")
return obj

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

r=returnExistedObj()
print(r)

结果如下:

1
2
__new__ is called
12

同时另一个需要注意的点是:

如果我们在__new__函数中不返回任何对象,则__init__函数也不会被调用。

1
2
3
4
5
6
7
8
class notReturnObj(object):
def __new__(cls):
print("__new__ is called")

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

print(notReturnObj())

结果如下:

1
2
__new__ is called
None

可见如果__new__函数不返回对象的话,不会有任何对象被创建,__init__函数也不会被调用来初始化对象,__new__返回 None

总结

  1. __init__不能有返回值
  2. __new__函数直接上可以返回别的类的实例。如上面例子中的returnExistedObj类的__new__函数返回了一个int值。
  3. 只有在__new__返回一个新创建属于该类的实例时当前类的__init__才会被调用.
  4. image-20191120105155474