【发布时间】:2018-04-26 18:41:02
【问题描述】:
我有一个容器,其中包含一个对象的方法,可能还有一些描述符。我想通过检查它们是否有一个'get'方法来测试描述符是否已经被解包。令我惊讶的是,类方法的__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)
【问题讨论】:
-
你是在问为什么
types.MethodType.__get__存在,还是在你的标题中问更一般的问题? -
另外,考虑到大多数非数据描述符将从
__get__返回一个普通的旧函数。有关示例,请参见描述符 HOWTO 末尾的纯 PythonClassMethod。而且函数显然必须是非数据描述符,否则方法根本无法工作。
标签: python python-3.x descriptor getattr getattribute