[Aktualisiert]: Antwort inline unter der Frage
Ich habe ein Inspektionsprogramm und ein Ziel ist es, dass die Logik in einem Dekorator weiß, ob die Funktion, die er dekoriert, eine Klassenmethode oder eine reguläre Funktion ist. Dies schlägt auf eine seltsame Weise fehl. Unten ist der Code in Python 2.6 ausgeführt:
def decorate(f):
print 'decorator thinks function is', f
return f
class Test(object):
@decorate
def test_call(self):
pass
if __name__ == '__main__':
Test().test_call()
print 'main thinks function is', Test().test_call
Dann bei der Ausführung:
decorator thinks function is <function test_call at 0x10041cd70>
main thinks function is <bound method Test.test_call of <__main__.Test object at 0x100425a90>>
Jeder Anhaltspunkt auf, was schief geht, und wenn es möglich ist, für @decorate richtig zu folgern, dass test_call eine Methode ist?
[Antwort] Die unten stehende Antwort von Carl ist nahezu perfekt. Ich hatte ein Problem bei der Verwendung des Dekorators für eine Methode, die von Unterklassen aufgerufen wird. Ich habe seinen Code so angepasst, dass er einen im_func-Vergleich für Oberklassenmitglieder enthält:
ismethod = False
for item in inspect.getmro(type(args[0])):
for x in inspect.getmembers(item):
if 'im_func' in dir(x[1]):
ismethod = x[1].im_func == newf
if ismethod:
break
else:
continue
break