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