Wie verwende ich Methodenüberladung in Python?

Lesezeit: 10 Minuten

Wie verwende ich Methodenuberladung in Python
Benutzer1335578

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

Wie verwende ich Methodenuberladung in Python
agf

Es ist Methode Überlastungnicht Methode überschreiben. Und in Python erledigen Sie das alles in einer Funktion:

class A:

    def stackoverflow(self, i='some_default_value'):
        print 'only method'

ob=A()
ob.stackoverflow(2)
ob.stackoverflow()

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.

    – agf

    14. September 16 um 13:33 Uhr

Wie verwende ich Methodenuberladung in Python
Ehsan Keshavarzian

Sie können auch verwenden pythonlangutil:

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

1643916373 583 Wie verwende ich Methodenuberladung in Python
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

1643916373 638 Wie verwende ich Methodenuberladung in Python
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:

from typing import overload
@overload
def process(response: None) -> None:
    ...
@overload
def process(response: int) -> Tuple[int, str]:
    ...
@overload
def process(response: bytes) -> str:
    ...
def process(response):
    <actual implementation>

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.

1643916373 836 Wie verwende ich Methodenuberladung in Python
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

1643916374 711 Wie verwende ich Methodenuberladung in Python
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?

    – Mike S

    17. Mai 19 um 23:01 Uhr

1643916374 43 Wie verwende ich Methodenuberladung in Python
Seyfi

Ich schreibe meine Antwort in Python 3.2.1.

def overload(*functions):
    return lambda *args, **kwargs: functions[len(args)](*args, **kwargs)

Wie es funktioniert:

  1. overload nimmt eine beliebige Menge an Callables und speichert sie in Tupeln functionsgibt dann Lambda zurück.
  2. 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) 
    )

.

759220cookie-checkWie verwende ich Methodenüberladung in Python?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy