Why instancemethod when I can add functions to classes outside class body?

Terry Reedy tjreedy at udel.edu
Fri Jul 25 19:44:45 CEST 2003

"Anders J. Munch" <andersjm at dancontrol.dk> wrote in message
news:3f210717$0$76049$edfadb0f at dread11.news.tele.dk...
> "Ben Finney" <bignose-hates-spam at and-benfinney-does-too.id.au>
> > On 25 Jul 2003 07:18:15 +0200, Martin v. Löwis wrote:
> > > rimbalaya at yahoo.com (Rim) writes:
> > >> So what problem is the new.instancemethod() trying to solve?
> > >
> > > It has no side effects on the class it is an instancemethod of.
> >
> > So what side effects (i.e. what problem) is the
> > trying to solve?
> Assigning to the class changes the behaviour of all instances of
that class.

Since changing the behavior of all instances is precisely the purpose
of making such an assignment (of function to class as method), that is
a feature, not a problem.

>  new.instancemethod can be used to add a method to an  individual
> >>> class A: pass
> ...
> >>> a1 = A(); a2 = A()
> >>> a1.f = new.instancemethod(lambda self: "hi", a1, A)
> >>> a2.f()
> Traceback (most recent call last):
>   File "<stdin>", line 1, in ?
> AttributeError: A instance has no attribute 'f'
> >>> a1.f()
> 'hi'

So to answer the OP's question, the problem solved is that directly
assigning a function as an instance attribute binds the function as a
function, which means no *automatic* access to the instance and its
other attributes.  If such access is needed, the instance must be
passed explicitly, as in
a1.f = lambda self: repr(self)

Instancemethod adds the option of wrapping instance-specific functions
as bound methods getting the instance as an automatic first (self)
paramater, just like with class-wide methods.  In the 'hi' example
above, since the self (psuedo)param is is ignored,
a1.f = lambda: 'hi'
would have the same net effect.  However,
a1.f = new.instancemethod(lambda self: repr(self), a1, A)
requires the wrapping to avoid having to explicitly pass the instance.

Terry J. Reedy

More information about the Python-list mailing list