平常編寫Python代碼的過程當中,特別是Python新手,常常會遇到這樣的錯誤:html
TypeError: object() takes no parameters複製代碼
對於上面這個錯誤,很容易迷惑咱們,由於這個錯誤信息沒有很明確的指出,究竟是哪段代碼除了問題。那這個錯誤是怎麼產生的了,請聽我細細道來。python
在python中,方法是一個屬性,也就是說,當咱們調用一個方法時,python須要所屬方法名對應的屬性,好比說:git
o.m()複製代碼
python會如今對象o中搜索m屬性,若是對象o有m屬性(判斷對象o有沒有m屬性,能夠用hasattr函數)則調用它。bash
然而,python的方法是定義在一個class裏的,而不是object裏。也就是說若是m是o的方法,那就不多是它的屬性。正常狀況下,python會先搜索對象的屬性,若是沒有,再去搜索類的屬性,若是屬性存在,則能夠調用。(這地方可能你們會被類和對象兩個概念搞混,不太準確的來講,類就是class,對象就是實例,具體你們能夠查看文章笨辦法學Python)函數
在python中,大多數的類都繼承自object,在Python3中,若是你沒有指定繼承object,解釋器會自動給你加上,而Python若是你沒有指定,則爲old-style class。你們在平時編寫類時,建議你們都最好加上繼承object,這樣一個是代碼兼容性號,一個是比較優雅。spa
若是屬性在對象裏不存在,咱們會獲得一個錯誤信息,指明瞭哪一個地方的代碼有問題和出問題的緣由,可是和咱們上面說的錯誤code
TypeError: object() takes no parameters複製代碼
這個錯誤是我在建立對象實例時報的錯誤,例如:htm
class Foo(object):
pass複製代碼
若是我這樣:對象
f = Foo()複製代碼
就不會有任何問題,可是若是我這樣:繼承
f = Foo(10)複製代碼
而後我就會獲得上面的錯誤,這到底是爲何了?
這是由於Python在建立對象是,分爲兩個階段:第一個階段,對象是經過調用new方法來建立的,這個方法的細節咱們基本上不用關心。new方法並不會當即返回一個對象實例,new方法以後,會調用init方法來給對象增長新的屬性。對於上面的對象o,調用的就是
o.__init__()複製代碼
Python首先查找o的init方法,可是沒找到,而後查找父類的init方法,假設父類是上面的Foo,能夠方式init方法依然不存在,因此最後會找到object的init屬性。object的init是存在的,而且是個方法,而後調用這個方法,傳入相應的參數,可是object.init方法沒有參數,而後咱們就獲得的上面的錯誤。
TypeError: object() takes no parameters複製代碼
整個流程下來,最讓人迷惑的地方是,Python沒有這樣報錯:
「object.__init__()」 takes no parameters複製代碼
因而咱們無法定爲這個問題出在哪。
總結下來,在實現一個python的類時,最後寫上init方法,這樣就能夠避免這樣的迷惑性的錯誤。