Es gibt ein nützliches Ruby-Idiom, das tap
verwendet, was es Ihnen erlaubt, ein Objekt zu erstellen, einige Operationen daran auszuführen und es zurückzugeben (ich benutze eine Liste hier nur als Beispiel, mein wirklicher Code ist mehr involviert):
Bei Rails gibt es eine ähnliche Methode namens returning
, so dass Sie schreiben können:
was für sich spricht. Egal wie viel Sie für das Objekt bearbeiten, es ist immer noch klar, dass es sich um den Rückgabewert der Funktion handelt.
In Python muss ich schreiben:
%Vor% und ich frage mich, ob es eine Möglichkeit gibt, dieses Ruby-Idiom in Python zu portieren. Mein erster Gedanke war, with
statement zu verwenden, aber return with
ist keine gültige Syntax.
Sie können es wie folgt in Python implementieren:
%Vor%Verwendung:
%Vor%Allerdings wird es in Python 2.x nicht so oft verwendet wie in Ruby, da Lambda-Funktionen in Python ziemlich restriktiv sind. Zum Beispiel können Sie einen Aufruf nicht zum Drucken inline einreihen, da es sich um ein Schlüsselwort handelt. Sie können es daher nicht für Inline-Debugging-Code verwenden. Sie können dies in Python 3.x tun, obwohl es nicht so sauber wie die Ruby-Syntax ist.
%Vor%Kurze Antwort: Ruby fördert Methodenverkettung, Python nicht.
Ich denke, die richtige Frage ist: Wofür ist Rubys tap
nützlich?
Nun weiß ich nicht viel über Ruby, aber durch das Googeln habe ich den Eindruck, dass tap
konzeptionell als Kettenverkettung nützlich ist.
In Ruby ist der Stil: SomeObject.doThis().doThat().andAnotherThing()
ziemlich idiomatisch. Es basiert beispielsweise auf dem Konzept fließender Schnittstellen . Rubys tap
ist ein Sonderfall, in dem Sie SomeObject.doThis()
anstatt doThis
im laufenden Betrieb definieren.
Warum ich das alles erkläre? Weil es uns sagt, warum tap
keine gute Unterstützung in Python hat. Mit entsprechenden Vorbehalten kann Python die Verkettung nicht aufrufen .
Zum Beispiel geben Python-Listenmethoden im Allgemeinen None
zurück, anstatt die mutierte Liste zurückzugeben. Funktionen wie map
und filter
sind keine Listenmethoden. Auf der anderen Seite geben viele Ruby-Array-Methoden das modifizierte Array zurück.
Abgesehen von bestimmten Fällen wie einigen ORMs verwendet Python-Code keine fließenden Schnittstellen.
Am Ende ist es der Unterschied zwischen idiomatischem Ruby und idiomatischem Python. Wenn Sie von einer Sprache zur anderen gehen, müssen Sie anpassen.
Wenn Sie das schlimm genug haben möchten, können Sie einen Kontextmanager erstellen
%Vor%, die Sie verwenden können wie:
%Vor% Es kommt nicht um die return
Anweisung herum und with
macht hier wirklich nichts. Aber du hast Tap
gleich am Anfang, was dich auf die Funktion hindeutet, nehme ich an. Es ist besser als die Verwendung von Lambda, da Sie nicht auf Ausdrücke beschränkt sind und in der with
-Anweisung so ziemlich alles haben können, was Sie wollen.
Insgesamt würde ich sagen, wenn du tap
so schlecht willst, dann bleib bei Ruby und wenn du in Python programmieren musst, benutze Python, um Python und nicht Ruby zu schreiben. Wenn ich Ruby lerne, möchte ich Ruby schreiben;)
Kaum ein Ruby-Programmierer verwendet tap
auf diese Weise. In der Tat, alle Top-Ruby-Programmierer, die ich weiß, sagt tap
hat keinen Nutzen außer beim Debuggen.
Warum tust du das nicht einfach in deinem Code?
%Vor% und denken Sie daran, dass Array
eine flüssige Oberfläche unterstützt, so dass Sie dies sogar tun können:
Ich hatte eine Idee, dies mit Funktions-Dekoratoren zu erreichen, aber aufgrund der Unterscheidung in Python zwischen Ausdrücken und Anweisungen musste die Rückkehr am Ende sein.
Die Ruby-Syntax wird in meiner Erfahrung selten verwendet und ist weit weniger lesbar als der explizite Python-Ansatz. Wenn Python implizite Rückgabewerte oder eine Möglichkeit bietet, mehrere Anweisungen in einen einzelnen Ausdruck zu überführen, wäre dies machbar - aber es ist keines dieser Dinge beabsichtigt.
Hier ist meine - etwas sinnlose - Decorator Ansatz, als Referenz:
%Vor%Ich stimme teilweise mit anderen darin überein, dass es nicht viel Sinn macht, dies in Python zu implementieren. Wie auch immer, IMHO, Mark Byers Weg ist der Weg, aber warum Lambdas (und alles, was mit ihnen kommt)? Kannst du nicht eine separate Funktion schreiben, die bei Bedarf aufgerufen wird?
Eine andere Möglichkeit, das gleiche zu tun, könnte
sein %Vor%aber diese schöne Funktion ist in Python 3 nicht integriert, höre ich.