我正在学习classmethods
python 的概念.
class A(): n=0 # object method def func_o(self): self.n += 1 print self.n # well, class method @classmethod def func_c(cls): cls.n += 1 print cls.n
在检查callable()
类的属性时,我遇到了这个特殊的输出:
>>> [(k, callable(v)) for k,v in A.__dict__.items()] [('__module__', False), ('__doc__', False), ('func_o', True), ('func_c', False), ('n', False)]
('func_o', True)
即使班级__dict__
被检查,同样('func_c', False)
由于某种原因.
谁能解释一下?
一个classmethod
对象不是一个函数对象,没有.它并不意味着可以调用.
classmethod
对象是描述符 ; 描述符有助于将对象绑定到特定实例或类.函数和属性也是描述符; binding分别生成方法或属性值.请参阅Python描述符操作方法.如果要访问classmethod
类上的描述符,则会触发一个classmethod.__get__(None, cls)
生成绑定方法的调用(在调用时,调用原始函数,并将类对象作为第一个参数传入).
当您通过该__dict__
属性访问所有类属性时,您将绕过描述符协议,因此您可以自己获取原始描述符对象.
访问类上的对象(从而触发descriptor.__get__(None, cls)
将类方法绑定到类对象的调用),手动绑定或显式测试classmethod
对象:
>>> A.__dict__['func_c']>>> A.__dict__['func_c'].__get__(None, A) # explicitly bind to a class > >>> callable(A.__dict__['func_c'].__get__(None, A)) True >>> A.func_c # trigger the protocol and bind to a class >
您还可以classmethod
使用以下__func__
属性访问对象包装的原始函数:
>>> A.__dict__['func_c'].__func__
当然,它本身也可以调用.
请注意,这一切也适用于staticmethod
对象; 一个staticmethod
对象,在绑定时,只返回原始函数.