Was ist `1..__truediv__` ? Funktioniert die Python haben einen .. ("dot dot") - notation-syntax?
Kurzem stieß ich auf eine syntax, die ich nie zuvor gesehen, als ich erfuhr, python noch in den meisten tutorials, die ..
notation, es sieht wie folgt aus:
f = 1..__truediv__ # or 1..__div__ for python 2
print(f(8)) # prints 0.125
Dachte ich, es war genau das gleiche wie (außer es ist länger, natürlich):
f = lambda x: (1).__truediv__(x)
print(f(8)) # prints 0.125 or 1//8
Aber meine Fragen sind:
- Wie kann Sie das tun?
- Was bedeutet es eigentlich, mit den zwei Punkten?
- Wie können Sie es in eine komplexere Erklärung (wenn möglich)?
Dieser wird mir wohl sparen viele Zeilen code in der Zukunft...:)
- Hinweis:
(1).__truediv__
ist nicht wirklich das gleiche wie1..__truediv__
, wie der ehemalige Anrufeint.__truediv__
während die letztere hatfloat.__truediv__
. Alternativ können Sie auch1 .__truediv__
(mit Leerzeichen)` - Beachten Sie, dass
1//8
ist0
, nicht0.125
, in einer der beiden Versionen von Python. - erinnert mich an
if (x <- 3) {...}
- Hier ist ein Beispiel dafür.
- Wenn du gehst, schreiben einen lambda-Ausdruck, schreiben
lambda x: 1/x
, das ist ein Zeichen kürzer (die gleiche Länge, wenn Sie brauchen1./x
) Irgendetwas, das explizit aufrufen einer__method__
(außerhalb einer abgeleiteten Klasse, die das überschreiben dieser Methode) wahrscheinlich fällt in die Kategorie "dumm python tricks" - Spaß auf die Vernunft, über die aber fast sicher nicht, gehören in die Produktion von code. - Kannst du bitte eine Erklärung geben mit Ihrem Kommentar, so werden die Gründe, warum dies nicht getan werden, verständlich sind?
- Die hohe Qualität der Antworten und Kommentare, zeigen Sie den Beispielcode braucht Einsicht zu verstehen, ist erstaunlich, zu viele, hat alternativen, die sind übersichtlicher, mehr allgemein, und mindestens genauso effizient. Mein main gripe ist, dass die Lesbarkeit zählt. Speichern Klugheit, wo es am meisten gebraucht wird - die Kommunikation mit den Menschen.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Was Sie haben, ist ein
float
literal ohne die null zu schleppen, die Sie dann Zugriff auf die__truediv__
Methode. Es ist kein Betreiber in sich selbst; der erste Punkt ist Teil des float-Wert und der zweite ist der Punkt-operator zum Zugriff auf die Objekte, Eigenschaften und Methoden.Können Sie denselben Punkt erreichen, indem Sie Folgendes tun.
Weiteres Beispiel
Hier fügen wir hinzu 1.0 auf 2.0, was natürlich die Renditen 3.0.
1.0+2
kürzer?1..toString()
1+2
und.1+.2
. Mein schlechtes.Ist die Frage schon ausreichend beantwortet (d.h. @Paul Rooneys Antwort), aber es ist auch möglich, überprüfen Sie die Richtigkeit der Antworten.
Lassen Sie mich zum Schluss den vorhandenen Antworten:
..
ist nicht eine einzige syntax-element!Können Sie überprüfen, wie der source-code ist "tokenized". Diese Token stellen, wie der code interpretiert wird:
Also der string
1.
wird interpretiert als die Anzahl, die zweiten.
ist eine OP (ein operator, in diesem Fall die "get attribute" - operator) und die__truediv__
ist der name der Methode. Dies ist also nur der Zugriff auf die__truediv__
Methode der float1.0
.Andere Art der Betrachtung der erzeugte bytecode ist
dis
assemble es. Dies zeigt eigentlich die Anweisungen, die ausgeführt werden, wenn ein code ausgeführt wird:Die sagt im Grunde das gleiche. Es lädt das Attribut
__truediv__
von der ständigen1.0
.Bezüglich Ihrer Frage
Obwohl es möglich ist, sollten Sie nie code schreiben, der mag, einfach weil es nicht klar ist, was der code tut. Also bitte nicht verwenden es in komplexeren Aussagen. Ich würde sogar so weit gehen, dass Sie sollten nicht verwenden es bei so "einfachen" Aussagen, zumindest sollten Sie Klammern zum trennen der Anleitung:
dies wäre definitiv mehr lesbar, aber etwas entlang der Linien von:
wäre noch besser!
Ansatz mit
partial
bewahrt auch python-Datenmodell (die1..__truediv__
Ansatz nicht!) denen nachgewiesen werden kann, durch dieses kleine snippet:Dies ist, weil
1. /(1+2j)
wird nicht ausgewertet durchfloat.__truediv__
aber mitcomplex.__rtruediv__
-operator.truediv
stellt sicher, dass der reverse-Betrieb wird aufgerufen, wenn auf den normalen Betrieb zurückNotImplemented
aber Sie haben nicht diese fallbacks arbeiten wenn Sie auf__truediv__
direkt. Dieser Verlust des "erwarteten Verhalten" ist der Hauptgrund, warum man (normalerweise) sollte keine Magie benutzen Methoden direkt.Zwei Punkte zusammen kann ein wenig umständlich auf den ersten:
Aber es ist das gleiche wie das schreiben:
Weil
float
Literale geschrieben werden kann in drei Formen:1.__truediv__
nicht?.
scheint zu sein analysiert als Teil der Nummer, und dann die.
für die accessor-Methode fehlt.f
ist eine gebundene speziellen Methode auf einen float mit einem Wert von eins. Insbesonderein Python 3, ruft:
Beweis:
und:
Wenn wir das tun:
Behalten wir uns einen Namen gebunden, die gebundene Methode
Wenn wir Taten das, gepunktete Suche in einer engen Schleife, dies könnte sparen Sie ein wenig Zeit.
Parsen des Abstract-Syntax-Tree (AST)
Können wir sehen, dass analysieren des AST für den Ausdruck sagt uns, dass wir immer die
__truediv__
- Attribut auf die floating-point-Zahl,1.0
:Können Sie die gleiche Funktion aus:
Oder
Abzug
Können wir uns auch dort, nach Abzug.
Let ' s build it up.
1 selbst ist ein
int
:1 mit einem Punkt nach ist es ein float:
Den nächsten Punkt alleine wäre ein SyntaxError, aber es beginnt eine gepunktete lookup auf die Instanz des Schwimmers:
Sonst niemand hat erwähnt, dass dieses - Das ist jetzt ein "bound-Methode" auf den Schwimmer,
1.0
:Konnten wir erfüllen die gleiche Funktion, die viel mehr lesbar:
Leistung
Den Nachteil der
divide_one_by
Funktion ist, dass es erfordert eine andere Python-stack-frame, so dass es etwas langsamer ist als die gebundene Methode:Natürlich, wenn Sie nur mit normal-Literale, das ist noch schneller: