(望結交天下才士 ,Contact:UVEgMTkwNDUyOTQzOA==)python
__new__: 對象的建立,是一個靜態方法,第一個參數是cls。(想一想也是,不多是self,對象還沒建立,哪來的self)
__init__ : 對象的初始化, 是一個實例方法,第一個參數是self。
__call__ : 對象可call,注意不是類,是對象。ide
先有建立,纔有初始化。即先__new__,然後__init__。
上面說的很差理解,看例子。函數
1.對於__new__spa
1 class Bar(object): 2 pass 3 4 class Foo(object): 5 def __new__(cls, *args, **kwargs): 6 return Bar() 7 8 print Foo()
能夠看到,輸出來是一個Bar對象。代理
__new__方法在類定義中不是必須寫的,若是沒定義,默認會調用object.__new__去建立一個對象。若是定義了,就是override,能夠custom建立對象的行爲。
聰明的讀者可能想到,既然__new__能夠custom對象的建立,那我在這裏作一下手腳,每次建立對象都返回同一個,那不就是單例模式了嗎?沒錯,就是這樣。能夠觀摩《飄逸的python - 單例模式亂彈》
定義單例模式時,由於自定義的__new__重載了父類的__new__,因此要本身顯式調用父類的__new__,即object.__new__(cls, *args, **kwargs),或者用super()。,否則就不是extend原來的實例了,而是替換原來的實例。code
2.對於__init__對象
使用Python寫過面向對象的代碼的同窗,可能對 __init__ 方法已經很是熟悉了,__init__ 方法一般用在初始化一個類實例的時候。例如:blog
1 # -*- coding: utf-8 -*- 2 3 class Person(object): 4 """Silly Person""" 5 6 def __init__(self, name, age): 7 self.name = name 8 self.age = age 9 10 def __str__(self): 11 return '<Person: %s(%s)>' % (self.name, self.age) 12 13 if __name__ == '__main__': 14 piglei = Person('piglei', 24) 15 print piglei
這樣即是__init__最普通的用法了。但__init__其實不是實例化一個類的時候第一個被調用 的方法。當使用 Persion(name, age) 這樣的表達式來實例化一個類時,最早被調用的方法 實際上是 __new__ 方法。utf-8
3.對於__call__
對象經過提供__call__(slef, [,*args [,**kwargs]])方法能夠模擬函數的行爲,若是一個對象x提供了該方法,就能夠像函數同樣使用它,也就是說x(arg1, arg2...) 等同於調用x.__call__(self, arg1, arg2) 。模擬函數的對象能夠用於建立防函數(functor) 或代理(proxy).it
總結,在Python中,類的行爲就是這樣,__new__、__init__、__call__等方法不是必須寫的,會默認調用,若是本身定義了,就是override,能夠custom。既然override了,一般也會顯式調用進行補償以達到extend的目的。這也是爲何會出現"明明定義def _init__(self, *args, **kwargs),對象怎麼不進行初始化"這種看起來詭異的行爲。(注,這裏_init__少寫了個下劃線,由於__init__不是必須寫的,因此這裏不會報錯,而是當作一個新的方法_init__)