[英]Remove a property (getter/setter) from an attribute in subclass in python
[英]Remove attribute from subclass in Python
有沒有辦法從父類中存在的子類中刪除屬性?
在下面的例子中
class A(object):
foo = 1
bar = 2
class B(A):
pass
# <desired code here>
b = B()
assert hasattr(b, 'bar') == False
我們可以編寫任何代碼來使斷言通過嗎?
class A(object):
foo = 1
bar = 2
class B(A):
@property
def bar(self):
raise AttributeError
>>> b = B()
>>> b.bar
Traceback (most recent call last):
File "<pyshell#17>", line 1, in <module>
b.bar
File "<pyshell#15>", line 4, in bar
raise AttributeError
AttributeError
class nosubclasses(object):
def __init__(self, f, cls):
self.f = f
self.cls = cls
def __get__(self, obj, type=None):
if type == self.cls:
if hasattr(self.f, '__get__'):
return self.f.__get__(obj, type)
return self.f
raise AttributeError
例子:
In [2]: class MyClass(object):
...: x = 1
...:
In [3]: MyClass.x = nosubclasses(MyClass.x, MyClass)
In [4]: class MySubclass(MyClass):
...: pass
...:
In [5]: MyClass.x
Out[5]: 1
In [6]: MyClass().x
Out[6]: 1
In [80]: MySubclass.x
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-80-2b2f456dd101> in <module>()
----> 1 MySubclass.x
<ipython-input-51-7fe1b5063367> in __get__(self, obj, type)
8 return self.f.__get__(obj, type)
9 return self.f
---> 10 raise AttributeError
AttributeError:
In [81]: MySubclass().x
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-81-93764eeb9948> in <module>()
----> 1 MySubclass().x
<ipython-input-51-7fe1b5063367> in __get__(self, obj, type)
8 return self.f.__get__(obj, type)
9 return self.f
---> 10 raise AttributeError
AttributeError:
但正如評論者@delnan 指出的那樣,這違反了 Liskov 可替代性原則。 我的博客文章中的動機是有根據的,因為該屬性沒有描述對象本身。 但總的來說,這首先打破了能夠進行子類化的重點,這實際上就是擁有類的重點。
順便說一句,我的答案和@jamylak 的區別在於,在@jamylak 的答案中,屬性是按子類刪除的。 如果您創建了一個class C(A)
,它仍然具有bar
屬性。 在我的回答中,類本身(實際上是屬性)不允許子類擁有該屬性,因此一舉一動,所有子類都沒有它。
當我不希望在 dir(A) 中列出特定屬性(在本例中為“bar”)時,這對我有用。
class A(object):
foo = 1
bar = 2
class B(A):
def ___init__(self):
self.delete()
def delete(self):
delattr(self, 'bar')
基本上,在子類 B 中創建一個方法(刪除),刪除該屬性並將其放入構造函數中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.