Ich habe über magische Methoden in Python gelesen, und ich habe eine Menge Informationen über das Überschreiben von ihnen gefunden und welchen Zweck sie erfüllen, aber ich war nicht in der Lage, wo in der Sprache spezifische Operatoren und Aktionen zu finden sind Diesen Methoden zugeordnet ( +
sucht nach __add__
, +=
sucht nach __iadd__
, das Erstellen eines neuen Objekts aus einer Klasse könnte __new__
und __init__
aufrufen usw.) Gibt es irgendwo was ich sehen kann passiert, wenn der Python-Interpreter (oder welcher Mechanismus der unteren Ebene) auf ein Pluszeichen trifft?
Ihre Frage ist ein wenig generisch. Es gibt eine umfassende Liste von "speziellen Methoden", obwohl einige stdlib-spezifische Methoden fehlen ( zB __setstate__
und __getstate__
benutzt von pickle
usw. Aber es ist ein Protokoll des Moduls pickle
kein Sprachprotokoll).
Wenn Sie genau wissen wollen, was der Interpreter tut, können Sie das Modul dis
verwenden, um den Bytecode zu zerlegen:
Sie können sehen, dass der Intererper beim Hinzufügen einen BINARY_ADD
Byte-Code ausführt.
Wenn Sie genau sehen wollen, welche Operationen BINARY_ADD
ausführen, können Sie Pythons Quellcode herunterladen und die ceval.c
-Datei überprüfen:
So können wir sehen, dass Python Sonderfälle int und String-Ergänzungen, und schließlich fällt zurück auf PyNumber_Add
, die überprüft, ob der erste Operand __add__
implementiert und ruft es schließlich versucht __radd__
der rechten Hand Seite und wenn nichts funktioniert, erhöht TypeError
.
Beachten Sie, dass die Byte-Codes versionsspezifisch sind, daher zeigt dis
bei verschiedenen Versionen unterschiedliche Ergebnisse:
Auch der gleiche Byte-Code kann in zukünftigen Versionen optimiert werden, so dass selbst dann, wenn der Byte-Code der gleiche ist, unterschiedliche Versionen von Python tatsächlich unterschiedliche Anweisungen ausführen.
Wenn Sie erfahren möchten, wie python hinter den Kulissen funktioniert, empfehle ich Ihnen, einige C-Erweiterungen zu schreiben, indem Sie den Anleitungen und der Dokumentation folgen, die Sie auf der offiziellen Python-Website finden.
dis
Modul kann Ihnen dabei etwas helfen:
Nehmen wir ein Beispiel für eine einfache Liste:
%Vor% Es ist nicht trivial, den einzelnen Platz im CPython-Quellen-Mapping-Operator +
auf die spezielle Methode __add__
zu lokalisieren, da die Abstraktionsniveaus betroffen sind.
Wie andere geantwortet haben, wird +
mit dem Operanden BINARY_ADD
implementiert, der PyNumber_Add
aufruft (mit Ausnahme einiger speziell optimierter Fälle). PyNumber_Add
hingegen betrachtet das tp_as_number
Mitglied von Geben Sie das Objekt ein, um zum PyNumberMethods
Struktur, deren nb_add
-Member auf die C-Funktion zeigt, die die Addition implementiert.
Das ist alles klar für eingebaute Typen, die definieren Eigenen nb_add
, aber wie funktioniert Ihr __add__
, definiert in Python, übersetzt zu einem Funktionszeiger, der in nb_add
gespeichert ist? Dieser Teil wird von typeobject.c
gehandhabt: Wenn Sie eine Klasse definieren, die __add__
implementiert, wird die Maschine in typeobject.c
installiert in object->type->tp_as_number->nb_add
eine generische Funktion, die __add__
auf dem Objekt nachschlägt und sie aufruft, um den Zusatz zu implementieren. Für den Fall von __add__
heißt diese generische Funktion slot_nb_add
und ist definiert < Verwenden Sie dazu das Makro SLOT1BIN
.
Wie für __new__
und __init__
werden sie von% co_de aufgerufen % -Operator des __call__
-Objekts selbst ( type
in CPython-Implementierungssprache). Dies ist nur logisch, da Sie in Python den Typ aufrufen, um ein Objekt zu konstruieren.
Tags und Links python