[Tutor] Dict of function calls

Steven D'Aprano steve at pearwood.info
Thu Sep 23 03:33:33 CEST 2010


On Thu, 23 Sep 2010 09:21:27 am Pete wrote:

> > (3) There's no need to keep the instances floating around as
> > independent names, unless you need direct access to them.
> >
> > Putting these together, we get:
> >
> > dispatch_table = { 'foo': foo().do, 'bar': bar().do }
[...]
> I see. And are those methods then unbound?

No, they're bound methods.


> (Because when 
> instantiating the object it needs to do some initialization of
> instance variables, and I think those were not available when
> calling an unbound method. (My understanding of the bound/unbound
> method distinction is rather vague at this point, I apologise)

Don't apologise :)  This is a tutor list, and the bound/unbound thing 
is one of the trickier parts of Python. This is what we're here for!

The def keyword always creates a function, whether you are outside a 
class or inside. So *inside* a class, at *creation* time, a "method" 
is really an ordinary function. Here's an example that prints the 
so-called method while the class is being built:


>>> class Test(object):
...     def spam(self, n):
...             return 'spam'*n
...     print spam
...
<function spam at 0xb7ee14fc>


Once the class is created, the function object is wrapped to become a 
method. Methods can be bound or unbound. If you get the method from 
the class object itself, it will be unbound:

>>> Test.spam
<unbound method Test.spam>

You can still get access to the original function object like this:

>>> Test.spam.im_func
<function spam at 0xb7ee14fc>


If you then try to call the method, or the underlying function, you 
need to supply something as the "self" attribute. Method objects 
enforce that this first argument must be an instance of Test, but the 
underlying function object doesn't, so you can try passing anything 
you like and hope it works :)

Unbound methods are useful for when you know what method you want to 
call, but not which instance you want to call it on:

>>> func = str.upper
>>> # much later
...
>>> func("do you have any cheese, my good man?")
'DO YOU HAVE ANY CHEESE, MY GOOD MAN?'


If you get the method from an instance, it will be bound to that 
instance:

>>> Test().spam
<bound method Test.spam of <__main__.Test object at 0xb7eece2c>>

and self will automatically be provided when you call the method.


-- 
Steven D'Aprano 


More information about the Tutor mailing list