difference between class methods and instance methods

John john_sips_teaz at yahooz.com
Thu Feb 17 11:03:39 EST 2005


Duncan Booth wrote:
> John M. Gabriele wrote:
> 
> 
>>I've done some C++ and Java in the past, and have recently learned
>>a fair amount of Python. One thing I still really don't get though
>>is the difference between class methods and instance methods. I
>>guess I'll try to narrow it down to a few specific questions, but
>>any further input offered on the subject is greatly appreciated:
> 
> 
> I'll try not to cover the same ground as Steven did in his reply.
> 

Thanks for taking the time to reply Duncan.

> 
>>1. Are all of my class's methods supposed to take 'self' as their
>>first arg?
> 
> consider this:
> 
>   class Demo(object):
> 
>     def foo(self, x):
>         print self, x
>     @classmethod
>     def clsmethod(cls, x):
> 	print cls, x
>     @staticmethod
>     def stmethod(x):
> 	print x
> 
> 	
> 
> instance = Demo()
> 
> 
> Calling a bound method, you don't pass an explicit self parameter, but the 
> method receives a self parameter:
> 
> 
> bound = instance.foo
> bound(2)
> 
> <__main__.Demo object at 0x00B436B0> 2
 >
> Note that it doesn't matter whether you call instance.foo(2) directly, or 
> bind instance.foo to a variable first. Either will create a *new* bound 
> method object, and the correct instance is used for the call.

Za! What do you mean, "create a new bound method object"? I *already*
created that method when I def'd it inside the 'class Demo' statement,
no?

> This is 
> significantly different from languages such as C++ and Javascript which are 
> a real pain if you want to use a method as a callback.
> 
> Calling an unbound method, you pass a self parameter explicitly (and it 
> must be an instance of the class, *or an instance of a subclass*:
> 
> 
> unbound = Demo.foo
> unbound(instance, 2)
> 
> <__main__.Demo object at 0x00B436B0> 2

Ahhhhhhhh! See, coming from C++, the first thing I thought
when I saw what you just wrote was, "whoops, he shouldn't be
calling that instance method via the class name -- it's a bad
habit". Now I think I see what you mean: you may call an
instance method in two ways: via an instance where you don't
pass in anything for 'self', and via the class name, where
you must supply a 'self'.

> Again is doesn't matter whether you do this in one step or two. The usual 
> case for using an unbound method is when you have overridden a method in a 
> derived class and want to pass the call on to a base class. e.g.

Ok. Interesting.

> 
> class Derived(Demo):
> 
>     def foo(self, x):
>          Demo.foo(self, x)
> 
> A class method is usually called through the class rather than an instance, 
> and it gets as its first parameter the actual class involved in the call:
> 
> 
> Demo.clsmethod(2)
> 
> <class '__main__.Demo'> 2
> 
> Derived.clsmethod(2)
> 
> <class '__main__.Derived'> 2

Check.

> You can call a class method using an instance of the class, or of a 
> subclass, but you still the get class passed as the first parameter rather 
> than the instance:
> 
> 
> d = Derived
> d.clsmethod(2)
> 
> <class '__main__.Derived'> 2

Ok, so it looks like it may lead to confusion if you do that.
I wonder why the language allows it...


> A common use for class methods is to write factory functions. This is 
> because you can ensure that the object created has the same class as the 
> parameter passed in the first argument. Alternatively you can use class 
> methods to control state related to a specific class (e.g. to count the 
> number of instances of that exact class which have been created.)
> 
> There is no equivalent to a class method in C++.

Right. I see -- because in Python, a reference the actual class
object is implicitly passed along with the method call. Whereas,
C++ doesn't even have "class objects" to begin with.

> 
> Static methods are like static methods in C++. You can call them through 
> the class or a subclass, or through an instance, but the object used in the 
> call is not passed through to the method:
> 
> 
> Demo.stmethod(2)
> 
> 2
> 
> instance.stmethod(2)
> 
> 2
> 
> Derived.stmethod(2)
> 
> 2
> 
> d.stmethod(2)
> 
> 2
> 
> 
>>2. Am I then supposed to call them with MyClass.foo() or instead:
>>
>>    bar = MyClass()
>>    bar.foo()
>>?
> 
> 
> If you have an instance then use it. If the class method is a factory then 
> you might want to create a new object of the same type as some existing 
> object (but not a simple copy since you won't get any of the original 
> object's state). Mostly though you know the type of the object you want to 
> create rather than having an existing instance lying around.
> 
> 
>>3. Is "bound method" a synonym for instance method?
> 
> 
> Close but not quite. It is a (usually transient) object created from an 
> unbound instance method for the purposes of calling the method.

... hmm... bound methods get created each time you make
a call to an instance method via an instance of the given class?


>>4. Is "unbound method" a synonym for class method?
> 
> 
> Definitely not.

Right. :)

> 
>>And if anyone's *really* daring:
>>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...
> 
> 
> See above.
> 


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



More information about the Python-list mailing list