difference between class methods and instance methods

J

John M. Gabriele

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:

1. Are all of my class's methods supposed to take 'self' as their
first arg?

2. Am I then supposed to call them with MyClass.foo() or instead:

bar = MyClass()
bar.foo()
?

3. Is "bound method" a synonym for instance method?

4. Is "unbound method" a synonym for class method?

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

Much thanks,
---J
 
S

Steven Bethard

John said:
1. Are all of my class's methods supposed to take 'self' as their
first arg?

If by "class's methods" you mean methods on which you called
classmethod, then no, they shouldn't take a 'self' parameter, they
should take a 'cls' parameter because the first argument to the function
will be the class:

class C(object):
@classmethod
def f(cls, *args):
# do stuff

Undecorated methods (e.g. those that are not wrapped with classmethod or
staticmethod) should, on the other hand, take a 'self' parameter.
2. Am I then supposed to call them with MyClass.foo() or instead:

bar = MyClass()
bar.foo()

Classmethods should be called from the class. Python allows you to call
them from the instance, but this almost never does what you want, e.g.:

py> d = {}
py> d.fromkeys(range(4))
{0: None, 1: None, 2: None, 3: None}
py> d
{}

Note that 'd' is not updated -- I called a classmethod, not an
instancemethod. If I had called dict.fromkeys instead, this would have
been clearer.
3. Is "bound method" a synonym for instance method?

4. Is "unbound method" a synonym for class method?

No. To simplify things a little[1], a "bound method" is an instance
method that has been associated with a specific instance, and an
"unbound method" is an instance method that has not been associated with
a specific instance. Consider the difference between str.join and ''.join:

py> str.join
<method 'join' of 'str' objects>
py> ', '.join
<built-in method join of str object at 0x01233620>
py> str.join(['a', 'b', 'c'])
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
TypeError: descriptor 'join' requires a 'str' object but received a 'list'
py> ', '.join(['a', 'b', 'c'])
'a, b, c'
py> str.join(', ', ['a', 'b', 'c'])
'a, b, c'

In the example above, you can see that str.join is an "unbound method"
-- when I try to call it without giving it an instance, it complains.
On the other hand, ', '.join is a "bound method" because it has been
bound to a specific instance of str (in this case, the instance ', ').
When I call it without an instance, it doesn't complain because it's
already been bound to an instance.
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...

Staticmethods, like classmethods, are associated with the class object,
not the instance objects. The main difference is that when a
staticmethod is called, no additional arguments are supplied, while when
a classmethod is called, a first argument, the class, is inserted in the
argument list:

py> class C(object):
.... @classmethod
.... def f(*args):
.... print args
.... @staticmethod
.... def g(*args):
.... print args
....
py> C.f(1, 2, 3)
(<class '__main__.C'>, 1, 2, 3)
py> C.g(1, 2, 3)
(1, 2, 3)

STeVe

[1] Technically, I think classmethods could also considered to be "bound
methods" because in this case, the method is associated with a specific
instance of 'type' (the class in which it resides) -- you can see this
in the first argument that is supplied to the argument list of a
classmethod.
 
D

Duncan Booth

John said:
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:
def foo(self, x):
print self, x
@classmethod
def clsmethod(cls, x):
print cls, x
@staticmethod
def stmethod(x):
print x


Calling a bound method, you don't pass an explicit self parameter, but the
method receives a self parameter:
<__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*:
<__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.
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:
<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:
<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:
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.
 
J

John

Steven said:
If by "class's methods" you mean methods on which you called
classmethod, then no, they shouldn't take a 'self' parameter, they
should take a 'cls' parameter because the first argument to the function
will be the class:

class C(object):
@classmethod
def f(cls, *args):
# do stuff

Sorry -- I'm not as far along as you suspect. :) I've
never yet seen this "@classmethod" syntax. I'm supposing that
it's part of this so-called "new-style" class syntax.

When I ask "are all my class's methods...", I mean, when
I'm writing a class statement and the def's therein -- are
all those def's supposed to take 'self' as their first arg.

From your reply, I gather that, unless I'm using this special
syntax (@classmethod or @staticmethod), all my def's are supposed
to take 'self' as their first arg.
Undecorated methods (e.g. those that are not wrapped with classmethod or
staticmethod) should, on the other hand, take a 'self' parameter.

Ok. Check.

So then, are all def's -- that take 'self' as their first --
argument -- in a class statement, instance methods?

Classmethods should be called from the class. Python allows you to call
them from the instance, but this almost never does what you want, e.g.:

py> d = {}
py> d.fromkeys(range(4))
{0: None, 1: None, 2: None, 3: None}
py> d
{}

Note that 'd' is not updated -- I called a classmethod, not an
instancemethod. If I had called dict.fromkeys instead, this would have
been clearer.

Right. An important lesson in C++ as well.

3. Is "bound method" a synonym for instance method?

4. Is "unbound method" a synonym for class method?


No. To simplify things a little[1], a "bound method" is an instance
method that has been associated with a specific instance, and an
"unbound method" is an instance method that has not been associated with
a specific instance.

Ok! Now I'm making some headway. *This* is getting
at the crux of the biscuit.

Consider the difference between str.join and ''.join:

py> str.join
<method 'join' of 'str' objects>
>
py> ', '.join
<built-in method join of str object at 0x01233620>
>

Hmm... weird.
py> str.join(['a', 'b', 'c'])
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
TypeError: descriptor 'join' requires a 'str' object but received a 'list'
>

Right -- 'cause there's no actual instance of a string
to do the joining. Check.
py> ', '.join(['a', 'b', 'c'])
'a, b, c'
Check.

py> str.join(', ', ['a', 'b', 'c'])
'a, b, c'

Ack! Now you're creeping me out. Looking at the doc for str.join:

| py> help( str.join )
| Help on method_descriptor:
|
| join(...)
| S.join(sequence) -> string
|
| Return a string which is the concatenation of the strings in the
| sequence. The separator between elements is S.
|

It says that you didn't call that method correctly. Yet
it works anyway!? What's happening here?

In the example above, you can see that str.join is an "unbound method"
-- when I try to call it without giving it an instance, it complains. On
the other hand, ', '.join is a "bound method" because it has been bound
to a specific instance of str (in this case, the instance ', '). When I
call it without an instance, it doesn't complain because it's already
been bound to an instance.

Ok. I see that distinction. Thanks.


Staticmethods, like classmethods, are associated with the class object,
not the instance objects.

That makes sense.
The main difference is that when a
staticmethod is called, no additional arguments are supplied, while when
a classmethod is called, a first argument, the class, is inserted in the
argument list:

py> class C(object):
... @classmethod
... def f(*args):
... print args
... @staticmethod
... def g(*args):
... print args
...
py> C.f(1, 2, 3)
(<class '__main__.C'>, 1, 2, 3)
py> C.g(1, 2, 3)
(1, 2, 3)

STeVe

Thanks for that nice example. It looks like you're always
supposed to call both class and static methods via the class
name (rather than an instance name). I'll read up on what
this new @classmethod and @staticmethod syntax means.
[1] Technically, I think classmethods could also considered to be "bound
methods" because in this case, the method is associated with a specific
instance of 'type' (the class in which it resides) -- you can see this
in the first argument that is supplied to the argument list of a
classmethod.
 
J

John

Duncan said:
John M. Gabriele wrote:




I'll try not to cover the same ground as Steven did in his reply.

Thanks for taking the time to reply Duncan.
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




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.




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?

Definitely not.

Right. :)
 
D

Diez B. Roggisch

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

No, they get created when you create an actual instance of an object. So
only at construction time. Creating them means taking the unbound method
and binding the created object as first argument to the method. Thus each
instance of a class Foo with a method bar has its own instance of bar - the
bound method bar. But only one per object.
 
J

John

Diez said:
No, they get created when you create an actual instance of an object. So
only at construction time. Creating them means taking the unbound method
and binding the created object as first argument to the method. Thus each
instance of a class Foo with a method bar has its own instance of bar - the
bound method bar. But only one per object.

Ohhhhhhhh. Unlike C++, where methods are not first class objects
and you only have *one* that gets shared by all instances.

I'm getting it. Thanks for the reply. :)

---J
 
D

Diez B. Roggisch

Ohhhhhhhh. Unlike C++, where methods are not first class objects
and you only have *one* that gets shared by all instances.

Exactly - so unlike in c++, where you have to do ugly hacks if e.g. a C-lib
takes a callback and you want to pass an instance method, you can do that
in python. It's really great.
 
S

Steven Bethard

John said:
Sorry -- I'm not as far along as you suspect. :) I've
never yet seen this "@classmethod" syntax. I'm supposing that
it's part of this so-called "new-style" class syntax.

This is syntactic sugar in Python 2.4 for:

class C(object):
def f(cls, *args):
# do stuff
f = classmethod(f)

So if you'd like to check the docs, look in the builtins for classmethod
(and staticmethod):

http://docs.python.org/lib/built-in-funcs.html

From your reply, I gather that, unless I'm using this special
syntax (@classmethod or @staticmethod), all my def's are supposed
to take 'self' as their first arg.

Yup. You're of course welcome to name it whatever you like, but the
methods defined in your class (when not wrapped with classmethod,
staticmethod, etc.) will all be called with an instance of the class as
their first argument. So you need to make sure 'self' or something like
it is the first parameter to the function.
So then, are all def's -- that take 'self' as their first --
argument -- in a class statement, instance methods?

Basically, yes. (Again, assuming they're not wrapped with anything.)
Hmm... weird.

Ok, the point here is that str.join and ', '.join are not the same
object. The reason is that, when the ', ' instance of str is created,
new "bound method" objects are created for each of the instance methods
in str. These "bound methods" all know that the first argument to their
functions is ', '.
py> ', '.join(['a', 'b', 'c'])
'a, b, c'
Check.

py> str.join(', ', ['a', 'b', 'c'])
'a, b, c'
[snip]
What's happening here?

str.join is the "unbound method" of the str object. So just like you
have to declare 'self' as the first argument of all your instance
methods, the writer of the str object methods also declared 'self' as
the first argumetn to str.join. So str.join looks something like:

class str(object):
...
def join(self, sequence):
...

So when you access it like str.join(...) you should be passing it an
instance and a sequence. On the other hand, the "bound method" created
for ', ' has already bound the instance, so it no longer expects the
'self' argument to be passed in.

HTH,

STeVe
 
D

Duncan Booth

John said:
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?
The def statement creates a function.
Accessing the method through the class creates a brand new unbound method
from the function. Every access of the method through the class creates a
separate unbound method.

Accessing the method through the instance creates a brand new bound method.
Every such access creates a separate bound method.
... hmm... bound methods get created each time you make
a call to an instance method via an instance of the given class?
you've got it.
 
D

Duncan Booth

Diez said:
No, they get created when you create an actual instance of an object.
So only at construction time. Creating them means taking the unbound
method and binding the created object as first argument to the method.
Thus each instance of a class Foo with a method bar has its own
instance of bar - the bound method bar. But only one per object.
This is badly wrong. John was correct.

Bound methods get created whenever you reference a method of an instance.
If you are calling the method then the bound method is destroyed as soon as
the call returns. You can have as many different bound methods created from
the same unbound method and the same instance as you want:

Every reference to inst.foo is a new bound method.
 
J

John

Duncan said:
[snip]

Bound methods get created whenever you reference a method of an instance.
If you are calling the method then the bound method is destroyed as soon as
the call returns. You can have as many different bound methods created from
the same unbound method and the same instance as you want:


inst = C()
f1 = inst.foo
f2 = inst.foo
f1, f2

(<bound method C.foo of <__main__.C instance at 0x00B03F58>>, <bound method
C.foo of <__main__.C instance at 0x00B03F58>>)

I just wanted to interject, although those two hex
numbers in the above line are the same, calling
id() on f1 and f2 produces two *different* numbers,
which agrees with the point you made.
 
T

Terry Reedy

John M. Gabriele said:
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...

No, not at all. So called 'static methods' are class function attibutes
that are marked to *not* be given neither the method wrapping treatment nor
the first-arg binding treatment when accessed, but to be left as they are.
To me, this means that they are not methods but just functions.
.... def f(): pass
.... def g(): pass
.... g = staticmethod(g)
....<function g at 0x00888978>

Terry J. Reedy
 
A

Antoon Pardon

Op 2005-02-17 said:
No, they get created when you create an actual instance of an object.

I'm not so sure about that. Take the following code:
.... def m():
.... pass
.... False

If bound methods were created at instance creation one would expect
a True result here instead of False.
 
D

Duncan Booth

John said:
I just wanted to interject, although those two hex
numbers in the above line are the same, calling
id() on f1 and f2 produces two *different* numbers,
which agrees with the point you made.

Yes, note that the numbers are in the repr of C() and are actually
id(inst).

A common mistake seems to be for people to do:
(11803664, 11803664)

and conclude that the bound methods are the same. They aren't, but if you
just take the id of an object and throw it away then the next object of
similar size can [and with the current implementation probably will] be
allocated at the same location.
 
D

Diez B. Roggisch

This is badly wrong. John was correct.
Bound methods get created whenever you reference a method of an instance.
If you are calling the method then the bound method is destroyed as soon
as the call returns. You can have as many different bound methods created
from the same unbound method and the same instance as you want:

That did escape me so far - interesting. Why is it that way? I'd expect that
creating a bound method from the class and then storing it in the objects
dictionary is what happens.
 
D

Duncan Booth

Diez said:
That did escape me so far - interesting. Why is it that way? I'd
expect that creating a bound method from the class and then storing it
in the objects dictionary is what happens.
If you had a class with 50,000 methods it could take quite a while to
create instances, consider Zope as an example where every object acquires
large numbers of methods most of which are completely irrelevant. Even
outside Zope most objects never have all their methods called: dict, for
example, has 38 methods but most of them get little or no use.

Creating a bound method is a comparatively cheap operation, its a small
object which just has to hold references to the instance and the function.
The memory allocation is fast, because Python keeps lists of appropriately
sized buckets for small objects.
 
A

Antoon Pardon

Op 2005-02-18 said:
That did escape me so far - interesting. Why is it that way? I'd expect that
creating a bound method from the class and then storing it in the objects
dictionary is what happens.

No. What happens is that functions are descriptors. So if you
assign a function to a class attribute any access to this
attribute will call the __get__ method which will create a
bound method if the access was through an instance or an
unbound method if the access was through the class.
 
S

Steven Bethard

Duncan said:
If you had a class with 50,000 methods it could take quite a while to
create instances, consider Zope as an example where every object acquires
large numbers of methods most of which are completely irrelevant. Even
outside Zope most objects never have all their methods called: dict, for
example, has 38 methods but most of them get little or no use.

So why couldn't bound methods be created like lazy properties:

http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/363602

So that they're not created at instance creation time, but they're only
created once, when first accessed?

Not that I've ever had any problems with the speed or memory usage of
bound methods -- I'm just curious about the design decision.

STeVe
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,149
Members
46,695
Latest member
StanleyDri

Latest Threads

Top