difference between class methods and instance methods

Duncan Booth duncan.booth at invalid.invalid
Thu Feb 17 04:25:34 EST 2005


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.

> 
> 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. 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

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.

>>> 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

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

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++.

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.
> 
> 4. Is "unbound method" a synonym for class method?

Definitely not.

> 
> 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.




More information about the Python-list mailing list