摘要:正常情況下,會先搜索對象的屬性,如果沒有,再去搜索類的屬性,如果屬性存在,則可以調用。方法并不會立即返回一個對象實例,方法之后,會調用方法來給對象增加新的屬性。轉載自我的博客捕蛇者說
日常編寫Python代碼的過程中,特別是Python新手,經常會遇到這樣的錯誤:
TypeError: object() takes no parameters
對于上面這個錯誤,很容易迷惑我們,因為這個錯誤信息沒有很明確的指出,到底是哪段代碼除了問題。那這個錯誤是怎么產生的了,請聽我細細道來。
在python中,方法是一個屬性,也就是說,當我們調用一個方法時,python需要所屬方法名對應的屬性,比如說:
o.m()
python會現在對象o中搜索m屬性,如果對象o有m屬性(判斷對象o有沒有m屬性,可以用hasattr函數)則調用它。
然而,python的方法是定義在一個class里的,而不是object里。也就是說如果m是o的方法,那就不可能是它的屬性。正常情況下,python會先搜索對象的屬性,如果沒有,再去搜索類的屬性,如果屬性存在,則可以調用。(這地方可能大家會被類和對象兩個概念搞混,不太準確的來說,類就是class,對象就是實例,具體大家可以查看文章笨辦法學Python)
在python中,大多數的類都繼承自object,在Python3中,如果你沒有指定繼承object,解釋器會自動給你加上,而Python如果你沒有指定,則為old-style class。大家在平時編寫類時,建議大家都最好加上繼承object,這樣一個是代碼兼容性號,一個是比較優雅。
如果屬性在對象里不存在,我們會得到一個錯誤信息,指明了哪個地方的代碼有問題和出問題的原因,但是和我們上面說的錯誤
TypeError: object() takes no parameters
這個錯誤是我在創建對象實例時報的錯誤,例如:
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__方法,這樣就可以避免這樣的迷惑性的錯誤。
轉載自我的博客捕蛇者說文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/40915.html
摘要:本篇主要總結中綁定方法對象和未綁定方法對象的區別和聯系。在中使用描述器有翻譯的鏈接來表示具有綁定行為的對象屬性,使用描述器協議方法來控制對具有綁定行為屬性的訪問,這些描述器協議方法包括和。其中通過限定的必須使用實例才能調用。 本篇主要總結Python中綁定方法對象(Bound method object)和未綁定方法對象(Unboud method object)的區別和聯系。主要目的...
摘要:并且集合中的元素也是隨機排序的。除了用來創建集合,還可以使用的方式,但是這種方式不提倡使用,因為在某些情況下,搞不清楚是字典還是集合。集合不是序列類型,不能用索引方式對其進行修改和實現集合和列表兩種對象之間的轉化。 集合Set類似字典的特點,可以用{}花括號來定義;其中的元素是沒有序列,也就是非序列類型的數據;而且集合中的元素不可重復,這就類似于dict鍵。 創建集合 >>> s1 =...
摘要:中,引入了其他很多語言都具備的模式匹配和默認參數語法糖,使得代碼簡潔了不少。模式匹配中需要注意的觸發默認值如下所示右側的元素會觸發左側的默認值。 ES6 中,引入了其他很多語言都具備的模式匹配和默認參數語法糖,使得代碼簡潔了不少。但是使用的時候還是有些細節需要注意。 模式匹配原理 模式匹配的種類 具體來說,有三種類型的模式匹配: 直接賦值 let a = 1; 對象模式 let...
摘要:中的類都是單例模式一天,一同事問我這樣一個問題。與方法屬于新式類,即屬于類。方法在實例被創建之后被調用,該方法僅僅是對方法創建的實例進行一些初始化操作。需要注意的是,在重寫方法與方法的參數應該保持一致,否則會有發生。 Python 中的類都是單例模式? 一天,一同事問我這樣一個問題。這是一個奇怪的問題,可能你也這么認為。這里先不做解釋,我們先來看看 __new__ 和 __init__...
以下是嚴格模式中需要注意的用法,這里需要強調的是:ES6 的 class 和 模塊內都是默認的嚴格模式。其實,js 開發也會逐步走向嚴格模式,這應該是個趨勢。 添加了保留字 protected,static 和 interface 在嚴格模式下,不可以用with() (function(){ //非嚴格模式 var a = {name: Bob}; with(a){ name ...
閱讀 3289·2023-04-25 14:35
閱讀 3422·2021-11-15 18:00
閱讀 2563·2021-11-12 10:34
閱讀 2493·2021-11-11 16:54
閱讀 3481·2021-10-08 10:12
閱讀 2767·2021-09-06 15:02
閱讀 3320·2021-09-04 16:48
閱讀 2801·2019-08-29 14:02