Héritage Python - comment désactiver une fonction
en C++ vous pouvez désactiver une fonction dans la classe parent en la déclarant comme privée dans la classe enfant. Comment cela peut-il être fait en Python? C'est-à-dire Comment puis-je cacher la fonction de parent de l'interface publique de l'enfant?
5 réponses
il n'y a vraiment pas de véritables attributs ou méthodes "privés" en Python. Une chose que vous pouvez faire est simplement de surcharger la méthode que vous ne voulez pas dans la sous-classe, et de soulever une exception:
>>> 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'
la méthode de kurosch pour résoudre le problème n'est pas tout à fait correcte, parce que vous pouvez toujours utiliser b.foo
sans obtenir de AttributeError
. Si vous n'invoquez pas la fonction, aucune erreur ne se produit. Voici deux façons dont je peux penser à faire cela:
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()
Barre utilise le "wrap" motif pour restreindre l'accès à l'objet enveloppé. Martelli a une bonne conversation traiter cette question. Baz utilise intégré implémenter le protocole de descripteur pour l'attribut remplacer.
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
Cela soulève un AttributeError
sur la propriété au lieu de quand la méthode est appelée.
je l'ai suggéré dans un commentaire, mais malheureusement n'ont pas la réputation de il encore.
class X(object):
def some_function(self):
do_some_stuff()
class Y(object):
some_function = None
cela peut conduire à des exceptions désagréables et difficiles à trouver, donc vous pouvez essayer ceci:
class X(object):
def some_function(self):
do_some_stuff()
class Y(object):
def some_function(self):
raise NotImplementedError("function some_function not implemented")
C'est le moyen le plus propre que je connaisse pour le faire.
outrepasser les méthodes et demander à chacune des méthodes outrepassées d'appeler votre méthode disabledmethods (). Comme ceci:
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()