A classmethod
object is not a function object, no. It is not meant to be callable.
classmethod
objects are descriptors; descriptors facilitate the binding of an object to a specific instance or class. Functions and properties are also descriptors; binding produces methods, or the property value, respectively. See the Python Descriptor How To. If you were to access a classmethod
descriptor on the class, then this triggers a classmethod.__get__(None, cls)
call that produces a bound method (which, when called, invokes the original function with the class object passed in as the first argument).
When you access all class attributes through the __dict__
attribute, you are bypassing the descriptor protocol, so you get the raw descriptor objects themselves.
Either access the object on the class (and thus trigger the descriptor.__get__(None, cls)
call that binds class methods to the class object), manually bind, or test explicitly for classmethod
objects:
>>> A.__dict__['func_c']
<classmethod object at 0x1018e6cc8>
>>> A.__dict__['func_c'].__get__(None, A) # explicitly bind to a class
<bound method classobj.func_c of <class __main__.A at 0x101c52328>>
>>> callable(A.__dict__['func_c'].__get__(None, A))
True
>>> A.func_c # trigger the protocol and bind to a class
<bound method classobj.func_c of <class __main__.A at 0x101c52328>>
You can also access the original function that the classmethod
object wraps, using the __func__
attribute:
>>> A.__dict__['func_c'].__func__
<function func_c at 0x101c59668>
which is, of course, itself callable too.
Note that this all applies to staticmethod
objects too; a staticmethod
object, when bound, just returns the original function.