試圖做到這一點可能是一個壞主意,但......
這似乎並沒有被通過,因爲如何查找B.x
作品由默認的「正確」的繼承做到這一點。當得到B.x
時x
首先在B
中查找,如果沒有找到,則在A
中搜索,但另一方面在設置或刪除B.x
時只搜索B
。因此,例如
>>> class A:
>>> x = 5
>>> class B(A):
>>> pass
>>> B.x
5
>>> del B.x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: class B has no attribute 'x'
>>> B.x = 6
>>> B.x
6
>>> del B.x
>>> B.x
5
在這裏我們看到,首先,我們似乎不能夠刪除B.x
,因爲它不存在(A.x
存在且得到什麼服務,當你評估B.x
)。然而,通過將B.x
設置爲6,B.x
將存在,它可以通過B.x
檢索並且被del B.x
刪除,由此它不再存在,所以之後A.x
將再次作爲對B.x
的響應。
你可以,另一方面做的是使用元類,使B.x
提高AttributeError
:
class NoX(type):
@property
def x(self):
raise AttributeError("We don't like X")
class A(object):
x = [42]
class B(A, metaclass=NoX):
pass
print(A.x)
print(B.x)
現在,當然純粹主義者可能會嚷嚷,這打破了LSP,但它不是那麼簡單。這一切都歸結爲如果你認爲你通過這樣做創建了一個子類型。 issubclass
和isinstance
方法表示是,但LSP表示否(因爲您從A
繼承,許多程序員會認爲「是」)。
的LSP意味着如果B
是A
子類型,然後我們可以使用B
每當我們可以使用A
,但由於我們不能做到這一點,而這樣做的構建,我們可以得出這樣的結論B
其實不是的亞型A
,因此不違反LSP。
這打破了[LSP](http://en.wikipedia.org/wiki/Liskov_substitution_principle)。你爲什麼想這樣做? – 2011-05-19 10:22:50
您想要刪除的'B'類'x'類變量確實存儲在'A .__ dict__'中,所以如果您設法刪除它,您也會刪除'A.x'。因此,最接近的是_hiding_'A.x',通過給'B'一個'x'類變量,就像@Keith在他的回答中所表明的那樣。 – 2011-05-19 11:08:06
@JBernardo:LSP和靜態類型之間沒有太多聯繫。 LSP是一個合理的原則,因爲它使得類層次結構以可預測和一致的方式運行。這同樣適用於靜態和動態類型的語言,不管它們是否提供違反LSP的手段。 – 2011-05-19 16:29:46