[更新]:回答以下问题
我有一个检查程序,一个目标是让装饰器中的逻辑知道它正在装饰的函数是类方法还是常规函数。这以一种奇怪的方式失败了。以下是在 Python 2.6 中运行的代码:
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
然后在执行时:
decorator thinks function is <function test_call at 0x10041cd70>
main thinks function is <bound method Test.test_call of <__main__.Test object at 0x100425a90>>
关于出了什么问题的任何线索,以及@decorate 是否有可能正确推断出 test_call 是一种方法?
[答案] 下面卡尔的回答几乎是完美的。在子类调用的方法上使用装饰器时遇到问题。我修改了他的代码以包含对超类成员的 im_func 比较:
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