Python: Wie funktioniert inspect.ismethod?

8

Ich versuche den Namen aller Methoden in meiner Klasse zu bekommen. Beim Testen des inspect-Moduls habe ich eine meiner Methoden um obj = MyClass.__dict__['mymethodname'] ersetzt.

Aber jetzt gibt inspect.ismethod(obj) False zurück, während inspect.isfunction(obj) True zurückgibt, und ich verstehe nicht warum. Gibt es eine seltsame Methode, Methoden als Methoden zu markieren, die mir nicht bekannt sind? Ich dachte nur, dass es in der Klasse definiert ist und self als erstes Argument verwendet.

    
Eskil 12.07.2010, 12:54
quelle

5 Antworten

7

Sie sehen einige Effekte der Python-Mechanismen hinter den Kulissen.

Wenn Sie f = MyClass.__dict__['mymethodname'] schreiben, erhalten Sie die rohe Implementierung von "mymethodname", was eine einfache Funktion ist. Um es aufzurufen, müssen Sie einen zusätzlichen Parameter, Klasseninstanz, übergeben.

Wenn Sie f = MyClass.mymethodname schreiben (beachten Sie das Fehlen von Klammern nach mymethodname), erhalten Sie eine ungebundene Methode der Klasse MyClass, die eine Instanz von MethodType ist, die die oben erhaltene Raw-Funktion umschließt. Um es aufzurufen, müssen Sie einen zusätzlichen Parameter, Klasseninstanz, übergeben.

Wenn Sie f = MyClass().mymethodname schreiben (beachten Sie, dass ich ein Objekt der Klasse MyClass erstellt habe, bevor Sie seine Methode verwenden), erhalten Sie eine gebundene Methode einer Instanz der Klasse MyClass. Sie müssen keine zusätzliche Klasseninstanz übergeben, da sie bereits darin gespeichert ist.

Um die umbrochene Methode (gebunden oder ungebunden) mit dem Namen zu erhalten, der als String angegeben wurde, verwenden Sie getattr , wie in Gnibbler . Zum Beispiel:

%Vor%

oder

%Vor%     
atzz 12.07.2010, 13:23
quelle
2

Verwenden Sie die Quelle

%Vor%

Das erste Argument, das self ist, ist nur per Konvention. Durch den Zugriff auf die Methode nach dem Namen des Dikters der Klasse umgehen Sie die Bindung, daher scheint es eine Funktion und keine Methode zu sein

Wenn Sie auf die Methode mit Namen zugreifen möchten, verwenden Sie

%Vor%     
John La Rooy 12.07.2010 13:06
quelle
1

Nun, meinen Sie, dass obj.mymethod eine Methode ist (mit implizit übergebenem self ), während Klass.__dict__['mymethod'] eine Funktion ist?

Grundsätzlich ist Klass.__dict__['mymethod'] die "rohe" Funktion, die von etwas, das descriptors genannt wird, in eine Methode umgewandelt werden kann. Dies bedeutet, dass jede Funktion einer Klasse sowohl eine normale Funktion als auch eine Methode sein kann, je nachdem, wie Sie darauf zugreifen. So funktioniert das Klassensystem in Python und ganz normal.

Wenn Sie Methoden wollen, können Sie nicht __dict__ aufrufen (was Sie sowieso nie tun sollten). Um alle Methoden zu erhalten, sollten Sie inspect.getmembers(Klass_or_Instance, inspect.ismethod)

ausführen

Sie können die Details hier lesen, die Erklärung hierzu finden Sie unter "Benutzerdefinierte Methoden".

    
Jochen Ritzel 12.07.2010 13:10
quelle
1

Aus einem Kommentar in @ THC4ks Antwort sieht es so aus, als ob das OP zwischen eingebauten Methoden und Methoden, die in reinem Python-Code definiert sind, unterscheiden möchte. Benutzerdefinierte Methoden haben types.MethodType , aber eingebaute Methoden nicht.

Sie können die verschiedenen Typen wie folgt erhalten:

%Vor%

was druckt:

%Vor%     
Matt Anderson 12.07.2010 16:37
quelle
0

Sie könnten dir verwenden, um den Namen verfügbarer Methoden / Attribute / etc zu erhalten, und dann iterieren, um zu sehen, welche davon Methoden sind. So:

%Vor%

Ich erwarte, dass es eine sauberere Lösung gibt, aber das könnte etwas sein, das Sie verwenden könnten, wenn niemand anderes mit einem kommt. Ich hätte gerne, wenn ich keine Instanz der Klasse verwenden müsste, um getattribute zu verwenden.

    
Donald Miner 12.07.2010 13:07
quelle

Tags und Links