2008-10-23 14 views
24

In C++ können Sie eine Funktion in der Klasse von Eltern deaktivieren, indem Sie es in der Kindklasse als privat deklarieren. Wie kann das in Python gemacht werden? I.E. Wie kann ich die Funktion des Elternteils von der öffentlichen Schnittstelle des Kindes ausblenden?Python-Vererbung - wie man eine Funktion deaktiviert

Antwort

18

Es gibt wirklich nicht wahr „private“ Attribute oder Methoden in Python . Eine Sache, die Sie tun können, ist einfach die Methode überschreiben Sie nicht in der Unterklasse möchten, und heben eine Ausnahme:

>>> 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' 
+0

> Es gibt wirklich keine echten "privaten" Attribute oder Methoden in Python. Deshalb habe ich nicht gefragt, wie man sie privat macht, sondern wie man sie von der Schnittstelle "entfernt". Ich hoffe, dass die bearbeitete Version genauer ist. –

+2

Ich stimme zu, dass NotImplementedError wahrscheinlich der beste zu verwenden ist, aber wenn Sie wirklich wollen, dass die vererbte Methode überhaupt nicht vorhanden ist, dann rufen Sie AttributeError auf (was Sie bekommen würden, wenn der Elternteil Methode existierte nicht). –

+1

Guter Punkt in Bezug auf AttributeError. Ich werde mein Beispiel aktualisieren. – kurosch

5
class X(object): 
    def some_function(self): 
     do_some_stuff() 

class Y(object): 
    some_function = None 

Dies hängt zum Teil unangenehme und harte führen kann Ausnahmen zu finden, obwohl geworfen, so dass Sie diese könnten versuchen:

class X(object): 
    def some_function(self): 
     do_some_stuff() 

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

Kurosch Methode zur Lösung des Problems ist nicht ganz richtig, weil Sie noch b.foo verwenden können, ohne bekommen eine AttributeError. Wenn Sie die Funktion nicht aufrufen, tritt kein Fehler auf. Es gibt zwei Möglichkeiten, die ich denken kann, dies zu tun:

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 verwendet die „wrap“ Muster Zugriff auf das Objekt eingewickelt zu beschränken. Martelli has a good talk Umgang damit. Baz verwendet the property built-in, um das Deskriptorprotokoll für das zu überschreibende Attribut zu implementieren.

+2

Nun, sicher, in meiner Antwort ist es immer noch "sichtbar", aber Sie können es nicht per se "verwenden", weil es die Ausnahme auslösen wird. Ein gültiger Punkt. – kurosch

+2

+1, was ein kluger Trick, um eine "leere" Eigenschaft zu "löschen" foo Methode! : D – MestreLion

+0

Dadurch wird die Klasse für die Verwendung von Operatoren, die für Parent definiert sind, unterbrochen, da keine Unterklasse vorhanden ist. Auch '__getattr__' ist langsam – JBernardo

0

Dies ist der sauberste Weg, ich weiß es zu tun.

Überschreiben Sie die Methoden und rufen Sie jede der überschriebenen Methoden Ihre disabledmethods() -Methode auf. Wie folgt aus:

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

Eine Variation der Antwort von 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 

Dies wirft eine AttributeError auf dem Grundstück statt, wenn die Methode aufgerufen wird.

Ich hätte es in einem Kommentar vorgeschlagen, aber leider nicht den Ruf dafür haben.

+0

Wird dadurch AttributeError ausgelöst, wenn Sie 'getattr (b," Foo ")' aufrufen? Leider habe ich hier keinen Python-Interpreter, um es zu testen. –

+0

Wenn du 'getattr (b, 'foo') meinst, dann ja, es wird –

+0

Ja, das ist was ich meinte. Obwohl 'getattr (b, 'Foo')' dir auch einen Attributfehler geben wird, also keine Sorge da! –