В C++ вы можете отключить функцию в классе родителя, объявив ее закрытой в дочернем классе. Как это можно сделать в Python? И.Е. Как я могу скрыть функцию родителя от открытого интерфейса пользователя?Наследование Python - как отключить функцию
ответ
Там действительно не любой истинный «частные» атрибуты или методы в Python , Одна вещь, которую вы можете сделать, это просто переопределить метод, который вы не хотите в подклассе, и возбудит исключение: метод
>>> class Foo(object):
... def foo(self):
... print 'FOO!'
...
>>> class Bar(Foo):
... def foo(self):
... raise AttributeError("'Bar' object has no attribute 'foo'")
...
>>> b = Bar()
>>> b.foo()
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
File "<interactive input>", line 3, in foo
AttributeError: 'Bar' object has no attribute 'foo'
class X(object):
def some_function(self):
do_some_stuff()
class Y(object):
some_function = None
Это может привести к некоторым противным и трудно найти исключения бросают, хотя, так что вы можете попробовать это:
class X(object):
def some_function(self):
do_some_stuff()
class Y(object):
def some_function(self):
raise NotImplementedError("function some_function not implemented")
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()
Bar использует «завернуть» шаблон, чтобы ограничить доступ к обернутому объекту. Martelli has a good talk имеющий дело с этим. Baz использует the property built-in для реализации протокола дескриптора для переопределения атрибута.
Это самый чистый способ, который я знаю для этого.
Переопределите методы и попросите каждый из переопределенных методов вызвать метод disabledmethods(). Как это:
class Deck(list):
...
@staticmethod
def disabledmethods():
raise Exception('Function Disabled')
def pop(self): Deck.disabledmethods()
def sort(self): Deck.disabledmethods()
def reverse(self): Deck.disabledmethods()
def __setitem__(self, loc, val): Deck.disabledmethods()
Вариантом ответа kurosch:
class Foo(object):
def foo(self):
print 'FOO!'
class Bar(Foo):
@property
def foo(self):
raise AttributeError("'Bar' object has no attribute 'foo'")
b = Bar()
b.foo
Это поднимает AttributeError
на имущество, а не при вызове метода.
Я бы предположил это в комментарии, но, к сожалению, у него пока нет репутации.
> На самом деле нет истинных «частных» атрибутов или методов в Python. Вот почему я не спрашивал, как сделать их приватными, но как «удалить» их из интерфейса. Надеюсь, что отредактированная версия более точная. – 2008-10-23 23:03:46
Я согласен с тем, что NotImplementedError, вероятно, лучший, но если вы действительно хотите совместить с не унаследованным методом вообще, поднимите AttributeError (это то, что вы получите, если родительский метод не существует). – 2008-10-24 10:37:19
Хорошая точка относительно AttributeError. Я обновлю свой пример. – kurosch 2008-10-24 15:37:58