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 ---
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to