En C++, puede deshabilitar una función en la clase principal al declararla como privada en la clase secundaria. ¿Cómo se puede hacer esto en Python? ES DECIR. ¿Cómo puedo ocultar la función de los padres desde la interfaz pública del niño?Herencia de Python: cómo deshabilitar una función
Respuesta
Realmente no hay ninguna verdad "privado" atributos o métodos en Python . Una cosa que puede hacer es simplemente reemplazar el método no desea en la subclase, y elevar una excepción: Método
>>> 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
Esto puede conducir a una cierta desagradable y difícil de encontrar excepciones ser lanzado sin embargo, por lo que podría 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")
de kurosch de resolver el problema no es del todo correcto, porque todavía puede utilizar sin b.foo
obteniendo un AttributeError
. Si no invocas la función, no se produce ningún error. Aquí hay dos maneras que se me ocurre de hacerlo:
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 utiliza el patrón de "envolver" para restringir el acceso al objeto envuelto. Martelli has a good talk que trata de esto. Baz usa the property built-in para implementar el protocolo descriptor para el atributo anular.
Bueno, claro, en mi respuesta todavía es "visible", pero no se puede "usar" per se porque generará la excepción. Un punto válido, sin embargo. – kurosch
+1, ¡qué truco inteligente usar una propiedad "vacía" para "eliminar" el método foo! : D – MestreLion
Esto romperá la clase para el uso de operadores definidos en el padre porque no hay subclases. También '__getattr__' es lento – JBernardo
Esta es la manera más limpia que conozco para hacerlo.
Reemplace los métodos y haga que cada uno de los métodos reemplazados invoque su método disabledmethods(). De esta manera:
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()
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 plantea una AttributeError
en la propiedad en lugar de cuando se llama al método.
Lo hubiera sugerido en un comentario, pero desafortunadamente aún no tengo la reputación para él.
¿Aumentará AttributeError si llama a 'getattr (b," Foo ")'? Desgraciadamente, no tengo un intérprete de Python aquí para probarlo. –
si te refieres a 'getattr (b, 'foo')' entonces sí lo hará –
Sí, eso es lo que quise decir. Aunque 'getattr (b, 'Foo')' también te dará un error de Atributo, ¡así que no te preocupes! –
- 1. ¿Deshabilitar la herencia web.config?
- 2. Cómo deshabilitar una función específica de ReSharper 5.x
- 3. JavaScript herencia función
- 4. Herencia por defecto de Python?
- 5. Herencia de clase en Python
- 6. Python La herencia múltiple
- 7. Indicadores de función de miembro y herencia
- 8. ¿Deshabilitar el registro por método/función?
- 9. Python - Pasar una función a otra función
- 10. herencia en atributos de clase (python)
- 11. Herencia variable estática en Python
- 12. Anulación de la función de herencia múltiple de Python y ListView en django
- 13. Herencia: ¿Función que devuelve el tipo propio?
- 14. Python: herencia de las clases antiguas
- 15. Decoradores de Python y herencia de clase
- 16. Herencia de atributos en python usando __init__
- 17. Cómo deshabilitar la función de autocompletar en MVC Html Helper
- 18. ¿Miembro estático de una función en Python?
- 19. Python: enlace una función a una clave
- 20. Cómo deshabilitar la función de plantilla en Symfony2
- 21. Cómo deshabilitar la función de autocompletar en la idea
- 22. función virtual en herencia privada o protegida
- 23. Cómo tira de decoradores de una función en Python
- 24. Python: métodos metaclase + envueltos + herencia = problemas
- 25. ¿Cómo encontrar de dónde se importó una función en Python?
- 26. ¿Cómo crear una función de embalaje optimizada en python?
- 27. ¿Cómo puedo devolver dos valores de una función en Python?
- 28. ¿Cómo usar una función de comparación personalizada en Python 3?
- 29. ¿Cómo burlarse de una función gratuita en python?
- 30. ¿Cómo creo una función de Python con argumentos opcionales?
> Realmente no hay ningún verdadero atributo o método "privado" en Python. Es por eso que no pregunté cómo hacer que sean privados, sino cómo 'eliminarlos' de la interfaz. Espero que la versión editada sea más precisa. –
Estoy de acuerdo en que NotImplementedError es probablemente el mejor para usar, pero si realmente deseas que coincida con no tener el método heredado, levanta AttributeError en su lugar (que es lo que obtendrías si el padre el método no existía). –
Buen punto con respecto a AttributeError. Actualizaré mi ejemplo. – kurosch