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

    def bar(self):
        pass

class Water(Liquid):

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

4

5 回答 5

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()
于 2012-04-10T08:58:47.960 回答
2

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

于 2012-04-10T08:57:27.263 回答
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
于 2012-04-10T09:03:10.840 回答
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() 因为它不会修改类的基础

于 2012-04-10T09:45:25.587 回答
-1

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

我怀疑你可以通过使用slot attr 来做到这一点。

如果调用 bar ,则可能实现getattr方法并引发适当的异常。

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

于 2012-04-10T09:33:18.533 回答