it-swarm-eu.dev

Zweck von "return self" aus einer Klassenmethode?

Ich bin in einem Open-Source-Projekt auf so etwas gestoßen. Methoden, die Instanzattribute ändern, geben einen Verweis auf die Instanz zurück. Was ist der Zweck dieses Konstrukts?

class Foo(object):

  def __init__(self):
    self.myattr = 0

  def bar(self):
    self.myattr += 1
    return self
46
nate c

Es ist zu verketten.

Zum Beispiel:

var Car = function () {
    return {
        gas : 0,
        miles : 0,
        drive : function (d) {
            this.miles += d;
            this.gas -= d;
            return this;
        },
        fill : function (g) {
            this.gas += g;
            return this;
        },
    };
}

Jetzt können Sie sagen:

var c = Car();
c.fill(100).drive(50);
c.miles => 50;
c.gas => 50;
66
Josh K

Wie @Lie Ryan und @Frank Shearar erwähnen, wird dies als "fließende Schnittstelle" bezeichnet, aber dieses Muster gibt es schon sehr lange.

Der umstrittene Teil dieses Musters ist, dass Sie in OO einen veränderlichen Status haben, sodass eine void-Methode eine Art impliziten Rückgabewert von this hat - das Objekt mit dem aktualisierten Status ist also eine Art Rückgabewert .

In einer OO Sprache mit veränderlichem Zustand) sind diese beiden mehr oder weniger gleichwertig:

a.doA()
a.doB()
a.doC()

...im Gegensatz zu

a.doA().doB().doC()

Ich habe in der Vergangenheit gehört, dass Menschen sich fließenden Schnittstellen widersetzen, weil sie die erste Form mögen. Ein anderer Name, den ich für "fließende Schnittstelle" gehört habe, ist "Zugunglück";)

Ich sage jedoch "mehr oder weniger gleichwertig", weil fließende Schnittstellen eine Falte hinzufügen. Sie müssen dies nicht "zurückgeben". Sie können "neu zurückkehren". Auf diese Weise können unveränderliche Objekte in OO erreicht werden.

Sie könnten also eine Klasse A haben, die dies tut (Pseudocode)

function doA():
    return new A(value + 1)

function doB():
    return new A(value * 2)

function doC():
    return new A(sqrt(value))

Jetzt gibt jede Methode ein brandneues Objekt zurück, wobei das ursprüngliche Objekt unverändert bleibt. Und das ist eine Möglichkeit, in unveränderliche Objekte zu gelangen, ohne wirklich viel an Ihrem Code zu ändern.

10
Rob

Die meisten Sprachen kennen die Redewendung "return self" und ignorieren sie, wenn sie nicht in einer Zeile verwendet wird. Es ist jedoch bemerkenswert, dass Funktionen in Python standardmäßig None zurückgeben.

Als ich in der CS-Schule war, machte mein Ausbilder einen riesigen Deal über den Unterschied zwischen Funktionen, Verfahren, Routinen und Methoden; Viele handkrampfhafte Essayfragen wurden mit Druckbleistiften gemahlen, die mir wegen all dem heiß wurden.

Es genügt zu sagen, dass die Rückgabe von self die endgültige OO Methode zum Erstellen von Klassenmethoden ist, aber Python ermöglicht mehrere Rückgabewerte, Tupel, Listen, Objekte, Grundelemente oder Keine.

Verketten bedeutet, wie sie es ausdrücken, lediglich die Antwort auf die letzte Operation in die nächste zu setzen, und die Laufzeit von Python kann so etwas optimieren. Listenverständnisse sind eine eingebaute Form davon. (Sehr kraftvoll!)

In Python ist es also nicht so wichtig, dass jede Methode oder Funktion Dinge zurückgibt, weshalb der Standardwert None ist.

Es gibt eine Denkschule, dass jede Aktion in einem Programm ihren Erfolg, Misserfolg oder ihr Ergebnis an ihren aufrufenden Kontext oder Gegenstand zurückmelden sollte, aber dann hier nicht über DOD ADA-Anforderungen sprach. Wenn Sie Feedback zu einer Methode benötigen, fahren Sie fort oder nicht, aber versuchen Sie, konsequent zu sein.

Wenn eine Methode fehlschlagen kann, sollte sie Erfolg oder Misserfolg zurückgeben oder eine zu behandelnde Ausnahme auslösen.

Eine Einschränkung ist, dass Sie mit Python bei Verwendung der Rückgabesprache alle Variablen Methoden zuweisen können und möglicherweise glauben, dass Sie ein Datenergebnis oder eine Liste erhalten, wenn Sie das Objekt tatsächlich erhalten.

Typbeschränkende Sprachen schreien und schreien und brechen, wenn Sie dies versuchen, aber interpretierte Sprachen (Python, Lua, LISP) sind viel dynamischer.

8
Chris Reid

In Smalltalk hat jede Methode, die etwas nicht explizit zurückgibt, ein implizites "return self".

Das liegt daran, dass (a) wenn jede Methode etwas zurückgibt, das Rechenmodell einheitlicher wird und (b) es sehr nützlich ist, wenn Methoden sich selbst zurückgeben. Josh K gibt ein schönes Beispiel.

4
Frank Shearar

Vorteile der Rückgabe eines Objekts (return self)

  • Beispiel:

    print(foo.modify1().modify2())
    
    # instaed of
    foo.modify1()
    foo.modify2()
    print(foo)
    
  • Populärer Stil in der Programmiergemeinschaft (glaube ich).

Vorteile der Mutation eines Objekts (no return self)

  • Möglichkeit, return für andere Zwecke zu verwenden.
  • Guido van Rossum befürwortet diesen Stil (Ich bin mit seiner Argumentation nicht einverstanden).
  • Populärer Stil in Python Community (glaube ich).
  • Standard (weniger Quellcode).
2
xged