摘要:正常情況下,會(huì)先搜索對(duì)象的屬性,如果沒有,再去搜索類的屬性,如果屬性存在,則可以調(diào)用。方法并不會(huì)立即返回一個(gè)對(duì)象實(shí)例,方法之后,會(huì)調(diào)用方法來給對(duì)象增加新的屬性。轉(zhuǎn)載自我的博客捕蛇者說
日常編寫Python代碼的過程中,特別是Python新手,經(jīng)常會(huì)遇到這樣的錯(cuò)誤:
TypeError: object() takes no parameters
對(duì)于上面這個(gè)錯(cuò)誤,很容易迷惑我們,因?yàn)檫@個(gè)錯(cuò)誤信息沒有很明確的指出,到底是哪段代碼除了問題。那這個(gè)錯(cuò)誤是怎么產(chǎn)生的了,請(qǐng)聽我細(xì)細(xì)道來。
在python中,方法是一個(gè)屬性,也就是說,當(dāng)我們調(diào)用一個(gè)方法時(shí),python需要所屬方法名對(duì)應(yīng)的屬性,比如說:
o.m()
python會(huì)現(xiàn)在對(duì)象o中搜索m屬性,如果對(duì)象o有m屬性(判斷對(duì)象o有沒有m屬性,可以用hasattr函數(shù))則調(diào)用它。
然而,python的方法是定義在一個(gè)class里的,而不是object里。也就是說如果m是o的方法,那就不可能是它的屬性。正常情況下,python會(huì)先搜索對(duì)象的屬性,如果沒有,再去搜索類的屬性,如果屬性存在,則可以調(diào)用。(這地方可能大家會(huì)被類和對(duì)象兩個(gè)概念搞混,不太準(zhǔn)確的來說,類就是class,對(duì)象就是實(shí)例,具體大家可以查看文章笨辦法學(xué)Python)
在python中,大多數(shù)的類都繼承自object,在Python3中,如果你沒有指定繼承object,解釋器會(huì)自動(dòng)給你加上,而Python如果你沒有指定,則為old-style class。大家在平時(shí)編寫類時(shí),建議大家都最好加上繼承object,這樣一個(gè)是代碼兼容性號(hào),一個(gè)是比較優(yōu)雅。
如果屬性在對(duì)象里不存在,我們會(huì)得到一個(gè)錯(cuò)誤信息,指明了哪個(gè)地方的代碼有問題和出問題的原因,但是和我們上面說的錯(cuò)誤
TypeError: object() takes no parameters
這個(gè)錯(cuò)誤是我在創(chuàng)建對(duì)象實(shí)例時(shí)報(bào)的錯(cuò)誤,例如:
class Foo(object): pass
如果我這樣:
f = Foo()
就不會(huì)有任何問題,但是如果我這樣:
f = Foo(10)
然后我就會(huì)得到上面的錯(cuò)誤,這究竟是為什么了?
這是因?yàn)镻ython在創(chuàng)建對(duì)象是,分為兩個(gè)階段:第一個(gè)階段,對(duì)象是通過調(diào)用__new__方法來創(chuàng)建的,這個(gè)方法的細(xì)節(jié)我們基本上不用關(guān)心。__new__方法并不會(huì)立即返回一個(gè)對(duì)象實(shí)例,__new__方法之后,會(huì)調(diào)用__init__方法來給對(duì)象增加新的屬性。對(duì)于上面的對(duì)象o,調(diào)用的就是
o.__init__()
Python首先查找o的__init__方法,但是沒找到,然后查找父類的__init__方法,假設(shè)父類是上面的Foo,可以方式__init__方法依然不存在,所以最后會(huì)找到object的__init__屬性。object的__init__是存在的,并且是個(gè)方法,然后調(diào)用這個(gè)方法,傳入相應(yīng)的參數(shù),但是object.__init__方法沒有參數(shù),然后我們就得到的上面的錯(cuò)誤。
TypeError: object() takes no parameters
整個(gè)流程下來,最讓人迷惑的地方是,Python沒有這樣報(bào)錯(cuò):
“object.__init__()” takes no parameters
于是我們沒法定為這個(gè)問題出在哪。
總結(jié)下來,在實(shí)現(xiàn)一個(gè)python的類時(shí),最后寫上__init__方法,這樣就可以避免這樣的迷惑性的錯(cuò)誤。
轉(zhuǎn)載自我的博客捕蛇者說文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/40915.html
摘要:本篇主要總結(jié)中綁定方法對(duì)象和未綁定方法對(duì)象的區(qū)別和聯(lián)系。在中使用描述器有翻譯的鏈接來表示具有綁定行為的對(duì)象屬性,使用描述器協(xié)議方法來控制對(duì)具有綁定行為屬性的訪問,這些描述器協(xié)議方法包括和。其中通過限定的必須使用實(shí)例才能調(diào)用。 本篇主要總結(jié)Python中綁定方法對(duì)象(Bound method object)和未綁定方法對(duì)象(Unboud method object)的區(qū)別和聯(lián)系。主要目的...
摘要:并且集合中的元素也是隨機(jī)排序的。除了用來創(chuàng)建集合,還可以使用的方式,但是這種方式不提倡使用,因?yàn)樵谀承┣闆r下,搞不清楚是字典還是集合。集合不是序列類型,不能用索引方式對(duì)其進(jìn)行修改和實(shí)現(xiàn)集合和列表兩種對(duì)象之間的轉(zhuǎn)化。 集合Set類似字典的特點(diǎn),可以用{}花括號(hào)來定義;其中的元素是沒有序列,也就是非序列類型的數(shù)據(jù);而且集合中的元素不可重復(fù),這就類似于dict鍵。 創(chuàng)建集合 >>> s1 =...
摘要:中,引入了其他很多語言都具備的模式匹配和默認(rèn)參數(shù)語法糖,使得代碼簡(jiǎn)潔了不少。模式匹配中需要注意的觸發(fā)默認(rèn)值如下所示右側(cè)的元素會(huì)觸發(fā)左側(cè)的默認(rèn)值。 ES6 中,引入了其他很多語言都具備的模式匹配和默認(rèn)參數(shù)語法糖,使得代碼簡(jiǎn)潔了不少。但是使用的時(shí)候還是有些細(xì)節(jié)需要注意。 模式匹配原理 模式匹配的種類 具體來說,有三種類型的模式匹配: 直接賦值 let a = 1; 對(duì)象模式 let...
摘要:中的類都是單例模式一天,一同事問我這樣一個(gè)問題。與方法屬于新式類,即屬于類。方法在實(shí)例被創(chuàng)建之后被調(diào)用,該方法僅僅是對(duì)方法創(chuàng)建的實(shí)例進(jìn)行一些初始化操作。需要注意的是,在重寫方法與方法的參數(shù)應(yīng)該保持一致,否則會(huì)有發(fā)生。 Python 中的類都是單例模式? 一天,一同事問我這樣一個(gè)問題。這是一個(gè)奇怪的問題,可能你也這么認(rèn)為。這里先不做解釋,我們先來看看 __new__ 和 __init__...
以下是嚴(yán)格模式中需要注意的用法,這里需要強(qiáng)調(diào)的是:ES6 的 class 和 模塊內(nèi)都是默認(rèn)的嚴(yán)格模式。其實(shí),js 開發(fā)也會(huì)逐步走向嚴(yán)格模式,這應(yīng)該是個(gè)趨勢(shì)。 添加了保留字 protected,static 和 interface 在嚴(yán)格模式下,不可以用with() (function(){ //非嚴(yán)格模式 var a = {name: Bob}; with(a){ name ...
閱讀 3313·2023-04-25 14:35
閱讀 3427·2021-11-15 18:00
閱讀 2585·2021-11-12 10:34
閱讀 2505·2021-11-11 16:54
閱讀 3489·2021-10-08 10:12
閱讀 2771·2021-09-06 15:02
閱讀 3329·2021-09-04 16:48
閱讀 2806·2019-08-29 14:02