Ich versuche, Methodenüberladung in Python zu implementieren:
class A:
def stackoverflow(self):
print 'first method'
def stackoverflow(self, i):
print 'second method', i
ob=A()
ob.stackoverflow(2)
aber die Ausgabe ist second method 2; ähnlich:
class A:
def stackoverflow(self):
print 'first method'
def stackoverflow(self, i):
print 'second method', i
ob=A()
ob.stackoverflow()
gibt
Traceback (most recent call last):
File "my.py", line 9, in <module>
ob.stackoverflow()
TypeError: stackoverflow() takes exactly 2 arguments (1 given)
Wie mache ich das?
Stellen Sie sich in Python Methoden als einen speziellen Satz von “Attribute“, und es kann nur einen geben “Attribut” (und damit eine Methode) eines bestimmten Namens für ein Objekt. Die letzte Methode überschreibt alle bisherigen Methoden. In Java sind Methoden keine erstklassigen Bürger (sie sind keine “Attribute von Objekten”), sondern werden eher durch “Senden von Nachrichten” aufgerufen, die basierend auf dem nächstgelegenen Typ statisch aufgelöst werden (was ist where Überlastung kommt herein).
– Benutzer166390
18. April 12 um 5:06 Uhr
Siehe auch stackoverflow.com/questions/733264/…
– agf
18. April 12 um 5:08 Uhr
und stackoverflow.com/questions/6434482/python-function-overloading
– agf
18. April 12 um 5:32 Uhr
Warum wurde noch keine Antwort auf diese Frage akzeptiert? Klicken Sie einfach auf das ausgegrenzte Häkchen links neben Ihrer Lieblingsantwort…
– glglgl
22. Mai ’12 um 9:34 Uhr
mögliches Duplikat von überladenen Funktionen in Python?
– Ciro Santilli 新疆再教育营六四事件法轮功郝海东
14. Juli 15 um 18:47 Uhr
agf
Es ist Methode Überlastungnicht Methode überschreiben. Und in Python erledigen Sie das alles in einer Funktion:
Sie können in Python nicht zwei Methoden mit demselben Namen haben – und das müssen Sie auch nicht.
Siehe die Standardargumentwerte Abschnitt des Python-Tutorials. Sehen “Am wenigsten Erstaunen” und das veränderliche Standardargument für einen häufigen Fehler zu vermeiden.
Sehen PEP 443 für Informationen über die neuen generischen Funktionen für Einzeldispatch in Python 3.4.
und das brauchst du nicht – IMHO wäre es manchmal sehr praktisch, Methoden zu überladen, wie zB in C++. Ok, es ist nicht “notwendig” in dem Sinne, dass es nicht mit anderen Konstrukten gemacht werden kann – aber es würde einige Dinge einfacher und einfacher machen.
– Andreas Florath
18. April 12 um 6:09 Uhr
@AndreasFlorath Ich bin anderer Meinung. Lernen Sie Duck-Typing zu lieben und schreiben Sie jede Methode so, dass sie nur eine Sache macht und Methoden nicht überladen werden müssen.
– agf
18. April 12 um 7:05 Uhr
+1 dafür, dass ich über den “häufig zu vermeidenden Fehler” gelesen habe, bevor ich erwischt wurde
– mdup
10. September 13 um 11:27 Uhr
Ich möchte ein wenig widersprechen 😉 … Überladen macht den Code oft sauberer, weil Sie die Methode nicht mit zu vielen if-else-Anweisungen packen, um verschiedene Fälle zu behandeln. In gewisser Weise verwendet die ganze Bandbreite funktionaler Sprachen eine ähnliche Idee, dh den Vergleich von Argumentmustern. Was bedeutet, dass Sie kleinere, sauberere Methoden haben würden … anstatt riesige unlesbare.
– St
28. Februar 16 um 19:15 Uhr
@ user1019129 Das ist der Zweck der einzelnen generischen Dispatch-Funktionen, die in Python 3.4 hinzugefügt und in meiner Antwort verlinkt wurden.
from pythonlangutil.overload import Overload, signature
class A:
@Overload
@signature()
def stackoverflow(self):
print 'first method'
@stackoverflow.overload
@signature("int")
def stackoverflow(self, i):
print 'second method', i
Ich denke, das ist die einzig gültige Antwort auf die Frage. Ich würde doppelt abstimmen, wenn ich könnte.
– Michael
10. Oktober 17 um 15:55 Uhr
Es ist gut, aber es funktioniert nicht mit rohen Funktionen, sondern nur mit Methoden innerhalb einer Klasse.
– Legitimer Stapel
1. März 19 um 23:42 Uhr
@LegitStack Diese Funktionalität kann ebenfalls hinzugefügt werden. Es ist nicht unmöglich.
– Ehsan Keshavarzian
3. März 19 um 23:20 Uhr
@LegitStack Ich habe den Code auf GitHub aktualisiert, jetzt funktioniert er auch mit Funktionen.
– Ehsan Keshavarzian
6. August 19 um 2:40 Uhr
@PaulPrice Das ist richtig. Ich habe meine Antwort aktualisiert und den offiziellen Supportbereich entfernt. Sie können immer noch meinen Code verwenden, um Überladungen zu verteilen. Es funktioniert jetzt sowohl mit Methoden als auch mit Funktionen. Holen Sie sich den Code von GitHub. Ich habe PyPi noch nicht aktualisiert.
– Ehsan Keshavarzian
12. August 19 um 0:27 Uhr
Chris Morgan
In Python machen Sie das nicht so. Wenn Leute dies in Sprachen wie Java tun, wollen sie im Allgemeinen einen Standardwert (wenn nicht, wollen sie im Allgemeinen eine Methode mit einem anderen Namen). Also, in Python, Sie können Standardwerte haben.
class A(object): # Remember the ``object`` bit when working in Python 2.x
def stackoverflow(self, i=None):
if i is None:
print 'first form'
else:
print 'second form'
Wie Sie sehen können, Sie kann Verwenden Sie dies, um ein separates Verhalten auszulösen, anstatt nur einen Standardwert zu haben.
>>> ob = A()
>>> ob.stackoverflow()
first form
>>> ob.stackoverflow(2)
second form
Meist None ist nützlich, wenn Sie einen änderbaren Standardwert wünschen. Separates Verhalten sollte in separaten Funktionen sein.
– agf
18. April 12 um 4:58 Uhr
@agf: None kann auch als echter Vorgabewert nützlich sein.
– Chris Morgan
18. April 12 um 4:59 Uhr
Ja, aber ich bezog mich auf die Verwendung als Sentinel-Wert, wie Sie ihn in Ihrer Antwort verwenden, und wie ich denke, macht mein Kommentar deutlich.
– agf
18. April 12 um 5:02 Uhr
Sie sagen “allgemein”? meinst du das ist nicht immer so?
– joel
25. Juli 19 um 21:37 Uhr
Nein, die Leute möchten, dass sich die Funktion anders verhält und keinen “Standardwert” hat. Leicht unterschiedliche Verhaltensweisen für unterschiedliche Argumenttypen und Argumentanzahl.
– Gordon Zar
12. Januar um 10:56 Uhr
Omni
Lag agf früher mit der Antwort richtig, jetzt mit PEP-3124 Wir haben unseren syntaktischen Zucker.
Sehen Geben Sie die Dokumentation für Details ein auf der @overload Dekorateur, aber beachten Sie, dass dies wirklich nur syntaktischer Zucker ist und IMHO ist dies alles, worüber die Leute seitdem gestritten haben.
Persönlich stimme ich zu, dass mehrere Funktionen mit unterschiedlichen Signaturen es lesbarer machen, als eine einzelne Funktion mit mehr als 20 Argumenten zu haben, die alle auf einen Standardwert gesetzt sind (None die meiste Zeit) und dann mit endlos herumfummeln müssen if, elif, else Ketten, um herauszufinden, was der Aufrufer eigentlich will, dass unsere Funktion mit dem bereitgestellten Satz von Argumenten macht. Dies war nach dem Python-Zen längst überfällig:
Schön ist besser als hässlich.
und wohl auch
Einfach ist besser als komplex.
Direkt aus der oben verlinkten offiziellen Python-Dokumentation:
BEARBEITEN: Für alle, die sich fragen, warum dieses Beispiel nicht so funktioniert, wie Sie es von anderen Sprachen erwarten würden, würde ich vorschlagen, sich diese Diskussion anzusehen. Der @overloaded Funktionen sollen keine tatsächliche Implementierung haben. Dies geht aus dem Beispiel in der Python-Dokumentation nicht hervor.
Karl Knechtel
Sie können es nicht, müssen es nie und wollen es auch nicht wirklich.
In Python ist alles ein Objekt. Klassen sind Dinge, also sind sie Objekte. Methoden sind es auch.
Es gibt ein Objekt namens A was eine Klasse ist. Es hat ein Attribut namens stackoverflow. Es kann nur ein solches Attribut haben.
Wenn du schreibst def stackoverflow(...): ...was passiert, ist, dass Sie ein Objekt erstellen, das die Methode ist, und es der zuweisen stackoverflow Attribut von A. Wenn Sie zwei Definitionen schreiben, ersetzt die zweite die erste, so wie sich die Zuweisung immer verhält.
Außerdem möchten Sie keinen Code schreiben, der die wilderen Dinge tut, für die das Überladen manchmal verwendet wird. So funktioniert die Sprache nicht.
Anstatt zu versuchen, für jeden Typ von Dingen, die Sie erhalten könnten, eine separate Funktion zu definieren (was wenig Sinn macht, da Sie sowieso keine Typen für Funktionsparameter angeben), Hör auf, dir Gedanken über welche Dinge zu machen sind und fangen an, darüber nachzudenken, was sie können tun.
Sie können nicht nur kein separates schreiben, um ein Tupel im Vergleich zu einer Liste zu handhaben, sondern auch nicht wollen oder müssen.
Alles, was Sie tun, ist die Tatsache zu nutzen, dass beide zum Beispiel iterierbar sind (d. h. Sie können schreiben for element in container:). (Die Tatsache, dass sie nicht direkt durch Vererbung verwandt sind, ist irrelevant.)
TBH, ich wäre vorsichtiger mit “nie müssen”. Dies ist etwas, das jedem Merkmal jeder realen Welt und einer vollständigen Programmiersprache zugeordnet werden kann, und ist daher kein gültiges Argument. WHO braucht Generatoren? WHO braucht Klassen? Programmiersprachen sind nur syntaktischer Zucker für etwas Konkreteres.
– Sebastian Mach
22. Juni 18 um 14:30 Uhr
Völlig anderer Meinung. Mag sein, dass Sie „nie mussten“ oder „nie wollten“, aber es gibt genug Anwendungen, wo Sie es unbedingt wollen. Versuchen Sie zB, ein Programm zu schreiben, das sowohl Python- als auch numpy-Arrays elegant handhabt, ohne Ihr Programm mit instanceofs zu verunreinigen …
– Elmar Zander
22. August 18 um 19:29 Uhr
Basierend auf Masis Antwort würde ich sagen, dass “Sie können nicht” jetzt falsch und veraltet ist. Aufgrund der Existenz des @overload Als Dekorateur würde ich sagen, dass “ich will nicht wirklich” bestenfalls strittig ist. Aus PEP-3124: „… es ist derzeit ein gängiges Anti-Pattern für Python-Code, die Typen der empfangenen Argumente zu inspizieren … der ‚offensichtliche Weg‘ dafür ist die Typinspektion, aber das ist spröde und unzugänglich extension…” Es scheint also, als wollten genug Leute, dass es Teil von Python wurde.
– Mike S
16. November 18 um 22:09 Uhr
@ MikeS , der Standard @overload ist nur zum tippen.
– Noein
12. Mai 19 um 14:12 Uhr
@Narfanar Ich weiß nicht, wie Ihre Antwort auf meinen Kommentar zutrifft. Könntest du erklären?
– Mike S
17. Mai 19 um 23:01 Uhr
Peter Mortensen
Ich denke, das Wort, nach dem Sie suchen, ist “Überlastung”. In Python gibt es keine Methodenüberladung. Sie können jedoch wie folgt Standardargumente verwenden.
def stackoverflow(self, i=None):
if i != None:
print 'second method', i
else:
print 'first method'
Wenn Sie ihr ein Argument übergeben, folgt sie der Logik der ersten Bedingung und führt die erste Druckanweisung aus. Wenn Sie ihm keine Argumente übergeben, wird er in die gehen else Bedingung und Ausführung der zweiten drucken Erklärung.
TBH, ich wäre vorsichtiger mit “nie müssen”. Dies ist etwas, das jedem Merkmal jeder realen Welt und einer vollständigen Programmiersprache zugeordnet werden kann, und ist daher kein gültiges Argument. WHO braucht Generatoren? WHO braucht Klassen? Programmiersprachen sind nur syntaktischer Zucker für etwas Konkreteres.
– Sebastian Mach
22. Juni 18 um 14:30 Uhr
Völlig anderer Meinung. Mag sein, dass Sie „nie mussten“ oder „nie wollten“, aber es gibt genug Anwendungen, wo Sie es unbedingt wollen. Versuchen Sie zB, ein Programm zu schreiben, das sowohl Python- als auch numpy-Arrays elegant handhabt, ohne Ihr Programm mit instanceofs zu verunreinigen …
– Elmar Zander
22. August 18 um 19:29 Uhr
Basierend auf Masis Antwort würde ich sagen, dass “Sie können nicht” jetzt falsch und veraltet ist. Aufgrund der Existenz des @overload Als Dekorateur würde ich sagen, dass “ich will nicht wirklich” bestenfalls strittig ist. Aus PEP-3124: „… es ist derzeit ein gängiges Anti-Pattern für Python-Code, die Typen der empfangenen Argumente zu inspizieren … der ‚offensichtliche Weg‘ dafür ist die Typinspektion, aber das ist spröde und unzugänglich extension…” Es scheint also, als wollten genug Leute, dass es Teil von Python wurde.
– Mike S
16. November 18 um 22:09 Uhr
@ MikeS , der Standard @overload ist nur zum tippen.
– Noein
12. Mai 19 um 14:12 Uhr
@Narfanar Ich weiß nicht, wie Ihre Antwort auf meinen Kommentar zutrifft. Könntest du erklären?
overload nimmt eine beliebige Menge an Callables und speichert sie in Tupeln functionsgibt dann Lambda zurück.
Das Lambda nimmt eine beliebige Anzahl von Argumenten und gibt dann das Ergebnis des Aufrufs der gespeicherten Funktion zurück functions[number_of_unnamed_args_passed] mit Argumenten aufgerufen, die an das Lambda übergeben werden.
Verwendung:
class A:
stackoverflow=overload(
None,
#there is always a self argument, so this should never get called
lambda self: print('First method'),
lambda self, i: print('Second method', i)
)
.
7592200cookie-checkWie verwende ich Methodenüberladung in Python?yes
Stellen Sie sich in Python Methoden als einen speziellen Satz von “Attribute“, und es kann nur einen geben “Attribut” (und damit eine Methode) eines bestimmten Namens für ein Objekt. Die letzte Methode überschreibt alle bisherigen Methoden. In Java sind Methoden keine erstklassigen Bürger (sie sind keine “Attribute von Objekten”), sondern werden eher durch “Senden von Nachrichten” aufgerufen, die basierend auf dem nächstgelegenen Typ statisch aufgelöst werden (was ist where Überlastung kommt herein).
– Benutzer166390
18. April 12 um 5:06 Uhr
Siehe auch stackoverflow.com/questions/733264/…
– agf
18. April 12 um 5:08 Uhr
und stackoverflow.com/questions/6434482/python-function-overloading
– agf
18. April 12 um 5:32 Uhr
Warum wurde noch keine Antwort auf diese Frage akzeptiert? Klicken Sie einfach auf das ausgegrenzte Häkchen links neben Ihrer Lieblingsantwort…
– glglgl
22. Mai ’12 um 9:34 Uhr
mögliches Duplikat von überladenen Funktionen in Python?
– Ciro Santilli 新疆再教育营六四事件法轮功郝海东
14. Juli 15 um 18:47 Uhr