__new__、__init__、__call__三個特殊方法

用雙下劃線包圍的特殊方法在Python中又被成爲魔術方法,相似於C++等語言中的構造函數,這裏咱們就來詳解Python中的__new__、__init__、__call__三個特殊方法:
  • 1.__new__(cls, *args, **kwargs)  建立對象時調用,是一個靜態方法,返回當前對象的一個實例;   注意:這裏的第一個參數是cls即class自己
  • 2.__init__(self, *args, **kwargs) 建立完對象後調用,對當前對象的實例的一些初始化,無返回值,即在調用__new__以後,根據返回的實例初始化;注意,這裏的第一個參數是self即對象自己【注意和new的區別】
  • 3.__call__(self,  *args, **kwargs) 若是類實現了這個方法,至關於把這個類型的對象看成函數來使用,至關於 重載了括號運算符, 對象可call,注意不是類,是對象

先有建立,纔有初始化。即先__new__,然後__init__。
上面說的很差理解,看例子。python

1.對於__new__ide

class Bar(object): 
  pass 
 
class Foo(object): 
  def __new__(cls, *args, **kwargs): 
    return Bar() 
 
print Foo() 

 能夠看到,輸出來是一個Bar對象。函數

__new__方法在類定義中不是必須寫的,若是沒定義,默認會調用object.__new__去建立一個對象。若是定義了,就是override,能夠custom建立對象的行爲。
聰明的讀者可能想到,既然__new__能夠custom對象的建立,那我在這裏作一下手腳,每次建立對象都返回同一個,那不就是單例模式了嗎?沒錯,就是這樣。能夠觀摩《飄逸的python - 單例模式亂彈》
定義單例模式時,由於自定義的__new__重載了父類的__new__,因此要本身顯式調用父類的__new__,即object.__new__(cls, *args, **kwargs),或者用super()。,否則就不是extend原來的實例了,而是替換原來的實例。代理

2.對於__init__code

使用Python寫過面向對象的代碼的同窗,可能對 __init__ 方法已經很是熟悉了,__init__ 方法一般用在初始化一個類實例的時候。例如:對象

# -*- coding: utf-8 -*-

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__其實不是實例化一個類的時候第一個被調用 的方法。當使用 Persion(name, age) 這樣的表達式來實例化一個類時,最早被調用的方法 實際上是 __new__ 方法。blog

3.對於__call__
對象經過提供__call__(slef, [,*args [,**kwargs]])方法能夠模擬函數的行爲,若是一個對象x提供了該方法,就能夠像函數同樣使用它,也就是說x(arg1, arg2...) 等同於調用x.__call__(self, arg1, arg2) 。模擬函數的對象能夠用於建立防函數(functor) 或代理(proxy).utf-8

class Foo(object): 
  def __call__(self): 
    pass 
 
f = Foo()#類Foo可call 
f()#對象f可call 

總結,在Python中,類的行爲就是這樣,__new__、__init__、__call__等方法不是必須寫的,會默認調用,若是本身定義了,就是override,能夠custom。既然override了,一般也會顯式調用進行補償以達到extend的目的。
這也是爲何會出現"明明定義def _init__(self, *args, **kwargs),對象怎麼不進行初始化"這種看起來詭異的行爲。(注,這裏_init__少寫了個下劃線,由於__init__不是必須寫的,因此這裏不會報錯,而是當作一個新的方法_init__)it

相關文章
相關標籤/搜索