[英]Is there any way that I can restrict a child class from inheriting some of its parent's methods?
class Liquid(object):
def foo(self):
pass
def bar(self):
pass
class Water(Liquid):
Say, I have the two classes above, Water inherits from Liquid .说,我有上面的两个类, Water继承自Liquid 。 Is there any way I can restrict Water from inheriting one of the parent's methods, say
bar()
?有什么办法可以限制 Water 继承父方法之一,比如
bar()
?
Sort of.有点。 But don't do it.
但是不要这样做。
class Liquid(object):
def foo(self):
pass
def bar(self):
pass
class Water(Liquid):
def __getattribute__(self, name):
if name == 'bar':
raise AttributeError("'Water' object has no attribute 'bar'")
l = Liquid()
l.bar()
w = Water()
w.bar()
You can override the method to be a no-op, but you can't remove it.您可以将该方法重写为空操作,但不能删除它。 Doing so would violate one of the core principles of object-oriented design, namely that any object that inherits from some parent should be able to be used anywhere the parent is used.
这样做会违反面向对象设计的核心原则之一,即从某个父对象继承的任何 object 都应该能够在使用该父对象的任何地方使用。 This is known as the Liskov Substitution Principle.
这被称为 Liskov 替换原则。
You can, as the other answers, say, break one of the inherited methods.就像其他答案一样,您可以打破其中一种继承的方法。
The alternative is to refactor out the "optional" methods, and inherit from a baseclass that doesn't have them:另一种方法是重构“可选”方法,并从没有它们的基类继承:
class BaseLiquid(object):
def foo(self):
pass
class Barised(object):
def bar(self):
pass
class Liquid(BaseLiquid, Barised): pass
class Water(BaseLiquid):
def drip(self):
pass
This is probably not a good idea, but you could always use metaclasses to implement private attributes:这可能不是一个好主意,但您始终可以使用元类来实现私有属性:
def private_attrs(name, bases, attrs):
def get_base_attrs(base):
result = {}
for deeper_base in base.mro()[1:]:
result.update( get_base_attrs(deeper_base) )
priv = []
if "__private__" in base.__dict__:
priv = base.__private__
for attr in base.__dict__:
if attr not in priv:
result.update( {attr: base.__dict__[attr]} )
return result
final_attrs = {}
for base in bases:
final_attrs.update( get_base_attrs(base) )
final_attrs.update(attrs)
return type(name, (), final_attrs)
class Liquid(object):
__metaclass__ = private_attrs
__private__ = ['bar']
def foo(self):
pass
def bar(self):
pass
class Water(Liquid):
__metaclass__ = private_attrs
print Water.foo
print Water.bar
Output is: Output 是:
<unbound method Water.foo>
Traceback (most recent call last):
File "testing-inheritance.py", line 41, in <module>
print Water.bar
AttributeError: type object 'Water' has no attribute 'bar'
EDIT: This will mess up isinstance() because it doesn't modify bases of the class.编辑:这会弄乱 isinstance(),因为它不会修改class的基数。
http://docs.python.org/release/2.5.2/ref/slots.html http://docs.python.org/release/2.5.2/ref/slots.html
I suspect you can do this, by using the slots attr.我怀疑你可以通过使用slots attr 来做到这一点。
It might be possible implementing a getattr method and throwing the appropriate exception if bar is called.如果调用 bar,则可能实现getattr方法并抛出适当的异常。
However, I agree, you don't want to do this in practice, since its a sign of bad design.但是,我同意,你不想在实践中这样做,因为它是糟糕设计的标志。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.