import types
from functools import wraps
class profiled:
def __init__(self,func):
wraps(func)(self)
def __call__(self,*a,**k):
print("profiled.call")
return self.__wrapped__(*a,**k)
def __get__(self,instance,cls):
if instance is None: return self
foo=types.MethodType(self,instance)
print("profiled.get:",foo)
return foo
class spam:
@profiled
def bar(self,x):print(x)
if name == 'main':
s=spam()
print(s.__dict__,spam.__dict__,'\n')
f=s.bar
print(f,type(f),f.__dict__,sep='\n')
f("TEST") #f 已经是绑定的方法了,为什么还要调用__call__()
1
explist OP 输出:
{} {'__dict__': <attribute '__dict__' of 'spam' objects>, '__doc__': None, '__weakref__': <attribute '__weakref__' of 'spam' objects>, '__module__': '__main__', 'bar': <__main__.profiled object at 0x02A8BCF0>} profiled.get: <bound method spam.bar of <__main__.spam object at 0x70>> <bound method spam.bar of <__main__.spam object at 0x70>> <class 'method'> {'__annotations__': {}, '__wrapped__': <function spam.bar at 0x10>, '__qualname__': 'spam.bar', '__name__': 'bar', '__module__': '__main__', 'n': 0, '__doc__': None} profiled.call TEST |
2
billgreen1 2016-12-01 16:52:24 +08:00
因为 f 不是 bar ,而是 wrappered 过的 bar,本质上应该是 profiled 类吧
|
3
explist OP 看了下 MethodType 的源码,不是很明白这里面的原理:
class _C: def _m(self): pass MethodType = type(_C()._m) |