我有一个容器,里面有一个对象的方法,可能还有一些描述符。我想通过检查描述符是否有一个'get'方法来测试描述符是否已经展开。令我惊讶的是,class方法的__get__
方法返回的对象也有一个__get__
方法。你知道这种行为什么时候有用吗?它是否与重写派生类中的类方法有关?你知道吗
import inspect
class K:
@classmethod
def cm(cls, a, b, c):
pass
def get_attr_info(attr):
try:
sig = inspect.signature(attr)
except:
sig = None
attr_info = [
('id ', id(attr),),
('type ', type(attr),),
('hasattr ', '__get__', hasattr(attr, '__get__'),),
('hasattr ', '__call__', hasattr(attr, '__call__'),),
('SIG: ', sig,)
]
return attr_info
get_label = lambda tpl: ' '.join([str(x) for x in tpl[0:-1]]).ljust(20)
kinst = K()
cm = object.__getattribute__(type(kinst), '__dict__')['cm']
try:
for idx in range(0, 5):
info = get_attr_info(cm)
print('\n' + '\n'.join([get_label(tpl) + str(tpl[-1]) for tpl in info]))
cm = cm.__get__(kinst, type(kinst))
except AttributeError:
print(idx)
输出为:
id 44545808
type <class 'classmethod'>
hasattr __get__ True
hasattr __call__ False
SIG: None
id 6437832
type <class 'method'>
hasattr __get__ True
hasattr __call__ True
SIG: (a, b, c)
id 6437832
type <class 'method'>
hasattr __get__ True
hasattr __call__ True
SIG: (a, b, c)
id 6437832
type <class 'method'>
hasattr __get__ True
hasattr __call__ True
SIG: (a, b, c)
id 6437832
type <class 'method'>
hasattr __get__ True
hasattr __call__ True
SIG: (a, b, c)
由于未绑定的方法对象,您看到的特定行为是有意义的。回到Python2,如果你这么做了
Foo.useful_method
将计算为未绑定方法对象,类似于函数,但与函数略有不同。未绑定的方法对象需要一个__get__
,因此Bar().useful_method
会自动绑定self
,就像Foo.useful_method
在Bar
的定义期间对函数而不是未绑定的方法求值一样。你知道吗未绑定方法对象和绑定方法对象是用相同的类型实现的,因此绑定方法共享未绑定方法所拥有的相同的
__get__
方法。不过,对于绑定方法对象,__get__
只返回绑定方法对象,就好像不涉及描述符逻辑一样。你知道吗现在没有绑定的方法了,method对象的
__get__
方法是多余的,但是它还没有被删除。你知道吗相关问题 更多 >
编程相关推荐