new: 對象的創(chuàng )建,是一個(gè)靜態(tài)方法,第一個(gè)參數是cls。(想想也是,不可能是self,對象還沒(méi)創(chuàng )建,哪來(lái)的self)
init : 對象的初始化, 是一個(gè)實(shí)例方法,第一個(gè)參數是self。
call : 對象可call,注意不是類(lèi),是對象。
先有創(chuàng )建,才有初始化。即先__new__,而后__init__。
直接看代碼:
class Bar(object): pass class Foo(object): def __new__(cls, *args, **kwargs): return Bar() print Foo() 可以看到,輸出來(lái)是一個(gè)Bar對象。通俗一點(diǎn)就是,當你實(shí)例化一個(gè)對象的時(shí)候,就會(huì )執行__new__ 方法里面的方法。__new__方法在類(lèi)定義中不是必須寫(xiě)的,如果沒(méi)定義,默認會(huì )調用object.__new__去創(chuàng )建一個(gè)對象。如果定義了,就是override,可以custom創(chuàng )建對象的行為。
class Person(object): """Silly Person""" def __init__(self, name, age): self.name = name self.age = age def __str__(self): return '<Person: %s(%s)>' % (self.name, self.age) if __name__ == '__main__': piglei = Person('piglei', 24) print piglei這樣便是__init__最普通的用法了。但__init__其實(shí)不是實(shí)例化一個(gè)類(lèi)的時(shí)候第一個(gè)被調用 的方法。當使用 Persion(name, age) 這樣的表達式來(lái)實(shí)例化一個(gè)類(lèi)時(shí),最先被調用的方法 其實(shí)是 new 方法。
call 這個(gè)看代碼意會(huì )
#call.py 一個(gè)class被載入的情況下。class Next: List = [] def __init__(self,low,high) : for Num in range(low,high) : self.List.append(Num ** 2) def __call__(self,Nu): return self.List[Nu]如果 這樣使用:
b = Next(1,7)print b.Listprint b(2)輸出[1, 4, 9, 16, 25, 36]9但如果這樣使用:
b = Nextb(1,7)print b.Listprint b(2)$python ./call.py[1, 4, 9, 16, 25, 36] Traceback (most recent call last): File "cal.py", line 17, in <module> print b(2) TypeError: __init__() takes exactly 3 arguments (2 given)__init__是初始化函數,在生成類(lèi)的實(shí)例時(shí)執行。
而__call__是模擬()的調用,需要在實(shí)例上應用,因此這個(gè)實(shí)例自然是已經(jīng)執行過(guò)__init__了。
你所舉的后面那個(gè)例子:
b = Next
這并不是創(chuàng )建實(shí)例,而是將class賦給一個(gè)變量。因此后面使用b進(jìn)行的操作都是對Next類(lèi)的操作,那么其實(shí)就是:
Next(1,7)print Next.Listprint Next(2)
聯(lián)系客服