3 回答

TA貢獻(xiàn)1806條經(jīng)驗(yàn) 獲得超5個(gè)贊
在這種情況下,變量陰影是什么意思?
變量陰影在所有情況下都意味著相同的事情,與上下文無(wú)關(guān)。它被定義為一個(gè)變量“隱藏”了另一個(gè)同名變量。因此,當(dāng)發(fā)生變量遮蔽時(shí),有兩個(gè)或多個(gè)同名變量,它們的定義取決于它們的作用域(意味著它們的值可能因作用域而異)??焖偈纠?/p>
In [11]: def shadowing():
...: x = 1
...: def inner():
...: x = 2
...: print(x)
...: inner()
...: print(x)
...:
In [12]: shadowing()
2
1
請(qǐng)注意,我們inner()首先調(diào)用,它指定x為2,并按此打印2。但是,這并不改變x在外部范圍(即,第一x),由于x在inner被遮蔽的第一x。因此,在我們調(diào)用inner()并且調(diào)用返回之后,現(xiàn)在第一個(gè)x返回到作用域中,因此最后一個(gè)打印輸出1。
在這個(gè)特定示例中,您引用的原作者說(shuō)沒(méi)有發(fā)生陰影(并且要清楚:沒(méi)有發(fā)生在實(shí)例級(jí)別)。你會(huì)注意到,i在父呈現(xiàn)相同的值作為i在這個(gè)孩子。如果發(fā)生陰影,它們將具有不同的值,如上面的示例(即父級(jí)將擁有一個(gè)變量的副本,i而子級(jí)將擁有一個(gè)也名為 的變量的不同副本i)。然而,他們沒(méi)有。i是7在雙方家長(zhǎng)和孩子。原作者指出 Python 的繼承機(jī)制在這方面與 Java 不同。

TA貢獻(xiàn)1803條經(jīng)驗(yàn) 獲得超3個(gè)贊
在 Java 中,方法和字段是根本不同的東西,按照完全不同的規(guī)則運(yùn)行。子類只繼承方法;字段特定于聲明它們的類。如果子類聲明的字段與父類中的字段同名,則它們完全不相關(guān);父類的方法繼續(xù)訪問(wèn)父類的版本,子類的方法訪問(wèn)其版本。這就是所謂的陰影。如果父類真的想讓子類可以使用它的字段,它就必須為它定義 getter/setter 方法。
在 Python 中,沒(méi)有這樣的區(qū)別 - 方法基本上是其值恰好是一個(gè)函數(shù)的字段。此外,整個(gè)繼承層次結(jié)構(gòu)中的所有字段都存儲(chǔ)在單個(gè)命名空間中(通常實(shí)現(xiàn)為名為 的 dict 屬性__dict__
)。如果孩子和父母對(duì)某事使用相同的名稱,則他們必然指的是同一個(gè)對(duì)象。

TA貢獻(xiàn)1744條經(jīng)驗(yàn) 獲得超4個(gè)贊
當(dāng)在特定范圍(決策塊、方法或內(nèi)部類)內(nèi)聲明的變量與在外部范圍內(nèi)聲明的變量具有相同名稱時(shí),就會(huì)發(fā)生變量陰影。然后,您所在作用域中的變量會(huì)隱藏(隱藏/屏蔽)外部作用域中的變量。
在上面的代碼中,變量i在超類和子類中都被初始化。所以超類中的初始化會(huì)被子類和類中的初始化所掩蓋。
m = Child() #we initialized the child class with i=7
print(m.i) #eventhough we are calling a method in the super class the value of i in the super class is shadowed by the value we initialized the instance of the child class (m)
m.doStuff() #same thing here
添加回答
舉報(bào)