有没有什么方法可以限制子类继承其父类的一些方法?

时间:2012-04-10 08:54:43

标签: python inheritance python-2.7

class Liquid(object):
    def foo(self):
        pass

    def bar(self):
        pass

class Water(Liquid):

说,我上面有两个类, Water 继承自 Liquid 。有没有什么方法可以限制Water继承父母的一种方法,比如说bar()

5 个答案:

答案 0 :(得分:5)

排序。但是不要这样做。

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()

答案 1 :(得分:2)

您可以将该方法覆盖为无操作,但无法将其删除。这样做会违反面向对象设计的核心原则之一,即任何从父级继承的对象都应该能够在使用父级的任何地方使用。这被称为Liskov替代原则。

答案 2 :(得分:2)

正如其他答案所说,你可以打破一种继承的方法。

另一种方法是重构“可选”方法,并从没有它们的基类继承:

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

答案 3 :(得分:0)

这可能不是一个好主意,但您可以始终使用元类来实现私有属性:

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

输出是:

<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'

编辑:这会搞乱isinstance(),因为它不会修改类的基础

答案 4 :(得分:-1)

http://docs.python.org/release/2.5.2/ref/slots.html

我怀疑你可以使用插槽 attr。

来做到这一点

如果调用bar,可能会实现 getattr 方法并抛出相应的异常。

但是,我同意,你不想在实践中这样做,因为它是设计糟糕的标志。