Метод
kurosch для решения проблемы не совсем корректен, потому что вы все равно можете использовать b.foo
без получения AttributeError
. Если вы не вызываете функцию, ошибки не возникает. Вот два способа, которыми я могу подумать, чтобы сделать это:
import doctest
class Foo(object):
"""
>>> Foo().foo()
foo
"""
def foo(self): print 'foo'
def fu(self): print 'fu'
class Bar(object):
"""
>>> b = Bar()
>>> b.foo()
Traceback (most recent call last):
...
AttributeError
>>> hasattr(b, 'foo')
False
>>> hasattr(b, 'fu')
True
"""
def __init__(self): self._wrapped = Foo()
def __getattr__(self, attr_name):
if attr_name == 'foo': raise AttributeError
return getattr(self._wrapped, attr_name)
class Baz(Foo):
"""
>>> b = Baz()
>>> b.foo() # doctest: +ELLIPSIS
Traceback (most recent call last):
...
AttributeError...
>>> hasattr(b, 'foo')
False
>>> hasattr(b, 'fu')
True
"""
foo = property()
if __name__ == '__main__':
doctest.testmod()
Бар использует шаблон «обтекание», чтобы ограничить доступ к обернутому объекту. Мартелли хорошо говорит , имея дело с этим. Baz использует встроенное свойство для реализации протокола дескриптора для переопределения атрибута.