Ich schrieb einen Code, der "ungebundene Methoden" einer Klasse mit Introspektion findet und war überrascht, zwei verschiedene Arten von Deskriptoren für eingebaute Typen zu sehen:
%Vor%Suchen Sie die Dokumentation sehr begrenzt aufgedreht, aber interessant Ergebnisse:
inspect.getattr_static
nicht löst Deskriptoren und enthält einen Code, mit dem sie aufgelöst werden können. method_descriptor
beträgt mehr effizient als wrapper_descriptor
, aber nicht erklären, was sie sind:
Die Methoden
list.__getitem__()
,dict.__getitem__()
unddict.__contains__()
als jetzt umgesetzt method_descriptor Objekte anstatt wrapper_descriptor Objekte. Diese Form des Zugriffs verdoppelt ihre Leistung und macht sie für die Verwendung als Argumente für Funktionale besser geeignet:map(mydict.__getitem__, keylist)
.
Der Unterschied in der Leistung hat mich ziemlich fasziniert, klar, es gibt einen Unterschied , also habe ich nach weiteren Informationen gesucht.
Keine dieser Typen befindet sich im Modul types
:
mit help
liefert keine nützliche Information:
Suche im Internet kam nur mit Ergebnissen über up‚was ist ein Descriptor‘oder vage Hinweise auf die spezifischen Typen beteiligt.
Meine Frage ist also:
Was ist der tatsächliche Unterschied zwischen <class 'method_descriptor'>
und <class 'wrapper_descriptor'>
?
Es ist ein Implementierungsdetail. Auf C-Ebene definiert ein eingebauter Typ wie list
Methoden wie append
nach Name durch ein Array von PyMethodDef
structs, während spezielle Methoden wie __add__
indirekter definiert sind.
__add__
entspricht einem Funktionszeiger in einem der beiden Slots sq_concat
im tp_as_sequence
des Typs oder nb_add
im tp_as_number
des Typs. Wenn ein Typ einen dieser Slots definiert, generiert Python einen wrapper_descriptor
, der diesen Slot für die Methode __add__
der API auf Python-Ebene umschließt.
Der für type slots und PyMethodDef
structs erforderliche Wrapping ist etwas anders; Zum Beispiel könnten zwei Slots einer Methode entsprechen, oder ein Slot könnte sechs Methoden entsprechen. Slots tragen auch nicht ihre Methodennamen mit, während der Methodenname eines der Felder in PyMethodDef
ist. Da für die beiden Fälle unterschiedlicher Code benötigt wird, verwendet Python verschiedene Wrappertypen, um sie zu umbrechen.
Wenn Sie den Code sehen möchten, sind sowohl method_descriptor
als auch wrapper_descriptor
in implementiert Objects/descrobject.c
, mit struct typedefs in Include/descrobject.h
. Sie können den Code sehen, der die Wrapper in Objects/typeobject.c
initialisiert, wobei PyType_Ready
Delegaten an add_operators
für wrapper_descriptor
s und add_methods
für method_descriptor
s.
Es scheint, dass method_descriptor
und wrapper_descriptor
eine Art Callables sind, die in CPython verfügbar sind.
Der Unterschied zwischen ihnen scheint einfach zu sein
method_descriptor
wird anscheinend für die eingebauten Methoden verwendet
(implementiert in C) Objekte:
wrapper_descriptor
wird beispielsweise für die Operatoren von integrierten Typen verwendet:
Dies ist der Ort , wo ich diese Informationen gefunden habe.
Tags und Links python