Herencia Python – cómo deshabilitar una función

En C ++ puede deshabilitar una función en la clase del padre declarándola como privada en la clase del niño. ¿Cómo se puede hacer esto en Python? IE ¿Cómo puedo ocultar la función de los padres de la interfaz pública del niño?

Realmente no hay ningún atributo o método “privado” verdadero en Python. Una cosa que puede hacer es simplemente anular el método que no desea en la subclase y generar una excepción:

>>> 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 "", line 1, in  File "", line 3, in foo AttributeError: 'Bar' object has no attribute 'foo' 

El método de kurosch para resolver el problema no es del todo correcto, ya que aún puede usar b.foo sin obtener un AttributeError . Si no invoca la función, no se produce ningún error. Aquí hay dos maneras en que puedo pensar para hacer esto:

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

La barra utiliza el patrón de “ajuste” para restringir el acceso al objeto envuelto. Martelli tiene una buena charla sobre esto. Baz usa la propiedad incorporada para implementar el protocolo descriptor para que el atributo se invalide.

Una variación en la respuesta de 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 

Esto genera un AttributeError en la propiedad en lugar de cuando se llama al método.

Lo habría sugerido en un comentario, pero desafortunadamente todavía no tengo la reputación de hacerlo.

 class X(object): def some_function(self): do_some_stuff() class Y(object): some_function = None 

Sin embargo, esto puede hacer que se generen algunas excepciones desagradables y difíciles de encontrar, por lo que puede intentar esto:

 class X(object): def some_function(self): do_some_stuff() class Y(object): def some_function(self): raise NotImplementedError("function some_function not implemented") 

Esta es la forma más limpia que conozco para hacerlo.

Anule los métodos y haga que cada uno de los métodos anulados llame a su método disabledmethods (). Me gusta esto:

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