Unterschied zwischen "Wrapper" - und "Method" -Deskriptoren?

8

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:

  1. Ein Hinweis in dem Modul inspizieren dass inspect.getattr_static nicht löst Deskriptoren und enthält einen Code, mit dem sie aufgelöst werden können.
  2. behauptet gemacht href="https://docs.python.org/3.5/whatsnew/2.4.html?highlight=method_descriptor#optimizations"> dass method_descriptor beträgt mehr effizient als wrapper_descriptor , aber nicht erklären, was sie sind:
      

    Die Methoden list.__getitem__() , dict.__getitem__() und dict.__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 :

%Vor%

mit help liefert keine nützliche Information:

%Vor%

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'> ?

    
Tadhg McDonald-Jensen 14.06.2016, 19:27
quelle

2 Antworten

1

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.

    
user2357112 14.06.2016, 19:47
quelle
0

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:

%Vor%

wrapper_descriptor wird beispielsweise für die Operatoren von integrierten Typen verwendet:

%Vor%

Dies ist der Ort , wo ich diese Informationen gefunden habe.

    
Kamil 14.06.2016 19:48
quelle

Tags und Links