By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,402 Members | 1,047 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,402 IT Pros & Developers. It's quick & easy.

Why are class methods not classmethods?

P: n/a
There's some subtle behaviour going on here that I don't really follow.
Class methods apparently aren't classmethods.

>>class Parrot(object):
.... def method(self, *args):
.... return self, args
.... @classmethod
.... def cmethod(cls, *args):
.... return cls, args
....
>>type(parrot.method) # as expected
<type 'instancemethod'>
>>type(parrot.cmethod) # I don't expect this result
<type 'instancemethod'>
>>type(classmethod(parrot.method))
<type 'classmethod'>
>>>
parrot.cm = classmethod(parrot.method)
type(parrot.cm) # I expect this
<type 'classmethod'>
>>>
Parrot.CM = classmethod(parrot.method)
type(Parrot.CM) # but not this
<type 'instancemethod'>
Can anyone explain why class methods bound to a class are instancemethods
rather than classmethods?


--
Steven.
Nov 27 '07 #1
Share this Question
Share on Google+
2 Replies


P: n/a
On Tue, 27 Nov 2007 09:12:28 +0000, Steven D'Aprano wrote:
Can anyone explain why class methods bound to a class are instancemethods
rather than classmethods?
I'd say because they are bound to the class which is the instance that is
passed as first argument. Just like unbound methods turn into bound
methods when you access them on "normal" objects and change from
functions to instance methods, accessing class methods make them instance
methods too. If you bypass the dot operator you get the still unwrapped
class method:

In [83]: Parrot.cmethod
Out[83]: <bound method type.cmethod of <class '__main__.Parrot'>>

In [84]: type(Parrot.cmethod)
Out[84]: <type 'instancemethod'>

In [85]: Parrot.__dict__['cmethod']
Out[85]: <classmethod object at 0x9b26434>

In [86]: type(Parrot.__dict__['cmethod'])
Out[86]: <type 'classmethod'>

Ciao,
Marc 'BlackJack' Rintsch
Nov 27 '07 #2

P: n/a
On Nov 27, 2007 3:12 AM, Steven D'Aprano
<st****@remove.this.cybersource.com.auwrote:
There's some subtle behaviour going on here that I don't really follow.
Class methods apparently aren't classmethods.

>class Parrot(object):
... def method(self, *args):
... return self, args
... @classmethod
... def cmethod(cls, *args):
... return cls, args
...
>type(parrot.method) # as expected
<type 'instancemethod'>
>type(parrot.cmethod) # I don't expect this result
<type 'instancemethod'>
>type(classmethod(parrot.method))
<type 'classmethod'>
>>
parrot.cm = classmethod(parrot.method)
type(parrot.cm) # I expect this
<type 'classmethod'>
>>
Parrot.CM = classmethod(parrot.method)
type(Parrot.CM) # but not this
<type 'instancemethod'>
Can anyone explain why class methods bound to a class are instancemethods
rather than classmethods?

They're instancemethods bound to the type instance, rather than to an
instance of the type:
>>c = C()
c.method
<bound method C.method of <__main__.C object at 0x01B8F330>>
>>c.cmethod
<bound method type.cmethod of <class '__main__.C'>>
>>>
So rather than inventing special machinery for classmethods, Python
uses the existing instancemethod machinery and just changes the object
the instancemethod is bound to.
Nov 27 '07 #3

This discussion thread is closed

Replies have been disabled for this discussion.