Un objet classmethod
est un descripteur. Vous devez comprendre comment fonctionnent les descripteurs.
En bref, un descripteur est un objet qui présente un procédé __get__
, ce qui prend trois arguments: self
, un instance
et un instance type
.
lors de la recherche d'attribut normal, si un objet regardé-up A
a une méthode __get__
, cette méthode est appelée et ce qu'il retourne est substitué en place pour l'objet A
. C'est ainsi que les fonctions (qui sont aussi des descripteurs) deviennent des méthodes liées lorsque vous appelez une méthode sur un objet. Un objet classmethod
fonctionne de la même manière. Quand il est recherché, sa méthode __get__
est appelée. Le __get__
d'un classmethod rejette l'argument correspondant au instance
(s'il y en avait un) et ne passe que le instance_type
lorsqu'il appelle __get__
sur la fonction encapsulée.
Un doodle illustration:
In [14]: def foo(cls):
....: print cls
....:
In [15]: classmethod(foo)
Out[15]: <classmethod object at 0x756e50>
In [16]: cm = classmethod(foo)
In [17]: cm.__get__(None, dict)
Out[17]: <bound method type.foo of <type 'dict'>>
In [18]: cm.__get__(None, dict)()
<type 'dict'>
In [19]: cm.__get__({}, dict)
Out[19]: <bound method type.foo of <type 'dict'>>
In [20]: cm.__get__({}, dict)()
<type 'dict'>
In [21]: cm.__get__("Some bogus unused string", dict)()
<type 'dict'>
Plus d'informations sur les descripteurs peuvent être trouvés ici (entre autres): http://users.rcn.com/python/download/Descriptor.htm
Pour la tâche spécifique d'obtenir le nom de la fonction enveloppée par un classmethod
:
In [29]: cm.__get__(None, dict).im_func.__name__
Out[29]: 'foo'
Je n'ai pas d'idée sur le "missing" '__name__', mais pour être sûr que les méthodes de classe ont un wrapper' __call__'. – mjv