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
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'
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")
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.
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
+1, was ein kluger Trick, um eine "leere" Eigenschaft zu "löschen" foo Methode! : D – MestreLion
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
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()
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.
Wird dadurch AttributeError ausgelöst, wenn Sie 'getattr (b," Foo ")' aufrufen? Leider habe ich hier keinen Python-Interpreter, um es zu testen. –
Wenn du 'getattr (b, 'foo') meinst, dann ja, es wird –
Ja, das ist was ich meinte. Obwohl 'getattr (b, 'Foo')' dir auch einen Attributfehler geben wird, also keine Sorge da! –
> 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. –
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). –
Guter Punkt in Bezug auf AttributeError. Ich werde mein Beispiel aktualisieren. – kurosch