描述器类中__get__()的疑问

2016-11-30 00:21:16 +08:00
 explist

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__()
1403 次点击
所在节点    Python
4 条回复
explist
2016-11-30 00:26:20 +08:00
输出:
{} {'__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
billgreen1
2016-12-01 16:52:24 +08:00
因为 f 不是 bar ,而是 wrappered 过的 bar,本质上应该是 profiled 类吧
explist
2016-12-01 22:42:56 +08:00
看了下 MethodType 的源码,不是很明白这里面的原理:

class _C:
def _m(self): pass
MethodType = type(_C()._m)
explist
2016-12-01 22:59:40 +08:00
@explist
type(_c()._m) #这是创建类还是查看类型?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/324234

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX