difference between class methods and instance methods

John john_sips_teaz at yahooz.com
Thu Feb 17 10:38:50 EST 2005


Steven Bethard wrote:
> John M. Gabriele wrote:
> 
>> 1. Are all of my class's methods supposed to take 'self' as their
>> first arg?
> 
> 
> If by "class's methods" you mean methods on which you called 
> classmethod, then no, they shouldn't take a 'self' parameter, they 
> should take a 'cls' parameter because the first argument to the function 
> will be the class:
> 
> class C(object):
>     @classmethod
>     def f(cls, *args):
>         # do stuff

Sorry -- I'm not as far along as you suspect. :) I've
never yet seen this "@classmethod" syntax. I'm supposing that
it's part of this so-called "new-style" class syntax.

When I ask "are all my class's methods...", I mean, when
I'm writing a class statement and the def's therein -- are
all those def's supposed to take 'self' as their first arg.

 From your reply, I gather that, unless I'm using this special
syntax (@classmethod or @staticmethod), all my def's are supposed
to take 'self' as their first arg.

> Undecorated methods (e.g. those that are not wrapped with classmethod or 
> staticmethod) should, on the other hand, take a 'self' parameter.

Ok. Check.

So then, are all def's -- that take 'self' as their first --
argument -- in a class statement, instance methods?


>> 2. Am I then supposed to call them with MyClass.foo() or instead:
>>
>>     bar = MyClass()
>>     bar.foo()
> 
> 
> Classmethods should be called from the class.  Python allows you to call 
> them from the instance, but this almost never does what you want, e.g.:
> 
> py> d = {}
> py> d.fromkeys(range(4))
> {0: None, 1: None, 2: None, 3: None}
> py> d
> {}
> 
> Note that 'd' is not updated -- I called a classmethod, not an 
> instancemethod.  If I had called dict.fromkeys instead, this would have 
> been clearer.

Right. An important lesson in C++ as well.


>> 3. Is "bound method" a synonym for instance method?
>>
>> 4. Is "unbound method" a synonym for class method?
> 
> 
> No.  To simplify things a little[1], a "bound method" is an instance 
> method that has been associated with a specific instance, and an 
> "unbound method" is an instance method that has not been associated with 
> a specific instance. 

Ok! Now I'm making some headway. *This* is getting
at the crux of the biscuit.


> Consider the difference between str.join and ''.join:
> 
> py> str.join
> <method 'join' of 'str' objects>
 >
> py> ', '.join
> <built-in method join of str object at 0x01233620>
 >

Hmm... weird.

> py> str.join(['a', 'b', 'c'])
> Traceback (most recent call last):
>   File "<interactive input>", line 1, in ?
> TypeError: descriptor 'join' requires a 'str' object but received a 'list'
 >

Right -- 'cause there's no actual instance of a string
to do the joining. Check.

> py> ', '.join(['a', 'b', 'c'])
> 'a, b, c'

Check.

> py> str.join(', ', ['a', 'b', 'c'])
> 'a, b, c'

Ack! Now you're creeping me out. Looking at the doc for str.join:

| py> help( str.join )
| Help on method_descriptor:
|
| join(...)
|     S.join(sequence) -> string
|
|     Return a string which is the concatenation of the strings in the
|     sequence.  The separator between elements is S.
|

It says that you didn't call that method correctly. Yet
it works anyway!? What's happening here?


> In the example above, you can see that str.join is an "unbound method" 
> -- when I try to call it without giving it an instance, it complains. On 
> the other hand, ', '.join is a "bound method" because it has been bound 
> to a specific instance of str (in this case, the instance ', '). When I 
> call it without an instance, it doesn't complain because it's already 
> been bound to an instance.

Ok. I see that distinction. Thanks.



>> Where do the so-called "static methods" fit into all this?
>> By the name of them, it sounds like the same thing as class
>> methods...
> 
> 
> Staticmethods, like classmethods, are associated with the class object, 
> not the instance objects. 

That makes sense.

> The main difference is that when a 
> staticmethod is called, no additional arguments are supplied, while when 
> a classmethod is called, a first argument, the class, is inserted in the 
> argument list:
> 
> py> class C(object):
> ...     @classmethod
> ...     def f(*args):
> ...         print args
> ...     @staticmethod
> ...     def g(*args):
> ...         print args
> ...
> py> C.f(1, 2, 3)
> (<class '__main__.C'>, 1, 2, 3)
> py> C.g(1, 2, 3)
> (1, 2, 3)
> 
> STeVe

Thanks for that nice example. It looks like you're always
supposed to call both class and static methods via the class
name (rather than an instance name). I'll read up on what
this new @classmethod and @staticmethod syntax means.

> [1] Technically, I think classmethods could also considered to be "bound 
> methods" because in this case, the method is associated with a specific 
> instance of 'type' (the class in which it resides) -- you can see this 
> in the first argument that is supplied to the argument list of a 
> classmethod.



-- 
--- remove zees if replying via email ---



More information about the Python-list mailing list