I had a container holding an object's methods, and possibly some descriptors. I wanted to test whether the descriptors had already been unwrapped or not by checking whether they had had a 'get' method. To my surprise, the __get__
method of a class-method returns an object which also has a __get__
method. Do you know when this behavior is useful? Does it have something to do with overriding class methods in a derived class?
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)
The Output Is:
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)