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?

25
demandé sur Boris Gorelik 2008-10-24 02:40:55

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'
19
répondu kurosch 2008-10-24 15:43:01

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.

17
répondu cdleary 2008-10-25 00:05:19
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.

9
répondu John Damen 2014-04-17 06:41:17
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")
5
répondu Jason Baker 2008-10-24 05:55:58

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()
0
répondu Joey Nelson 2014-04-17 06:32:24