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