extending methods ?

Alex Martelli aleax at aleax.it
Wed Oct 1 06:11:58 EDT 2003


Arnd Baecker wrote:

> Hi,
> 
> the summary of my question is:
> is there a way to append commands to a method inherited from
> another class?

The canonical way to achieve that is to override the method,
and, within the override, call up to the superclass's
implementation.


> More verbose: Assume the following situation that I have
> a class class_A with several methods.
> In each of these methods quite a few computations take place
> and several variables are defined.

Ah, no way, then -- local variables of a method (just like
any other function) are totally internal to that method, and
there is absolutely no reasonable way to access them from
the outside.

> However, with several variables and several methods
> the code will not look nice.

A matter of opinion.  I find it much nicer to know that a
local variable is local, and an instance variable is not.

> (also efficiency is a bit of concern - presumably it shouldn't -

Right, it shouldn't.  Local variables are fast BECAUSE they
are local.  If they were non-local -- as you require, in order
to work with them from outside the defining method -- then
they wouldn't be fast.

>  to me here as in my application the methods
>  are used to plot dots, circles, triangles etc.
>  so that speed is really important)

I strongly doubt that the loss of speed due to making some
needed variable non-local is going to be measurable.  Taking
your example...:

[alex at lancelot python2.3]$ python timeit.py \
> -s 'class A:' \
> -s '  def method1(self, x): y = 5 * x + 1' \
> -s '  def method2(self, x): self.y = 5 * x + 1' \
> -s 'a=A()' \
> 'a.method1(23)'
1000000 loops, best of 3: 1.47 usec per loop

and the same with method2 instead: 1.66 usec per loop.

What makes you think that a "slow-down" of 190 nanoseconds,
i.e. about 13% on this method call, is gonna be SO crucial?

And if you ARE working in an environment where every single
nanosecond matter, then what about...:

[alex at lancelot python2.3]$ python timeit.py \
> -s 'class A:' \
> -s '  def method1(self, x): y = 5 * x + 1' \
> -s '  def method2(self, x): self.y = 5 * x + 1' \
> -s 'a=A()' \
- -s 'meth=a.method2' \
> 'meth(23)'
1000000 loops, best of 3: 1.25 usec per loop

See?  Extracting the bound method once and for all saves
you a whopping *410* nanoseconds per call, compensating
the 190 "lost" by making instance variables where you need
them *and then some*.  In other words, there are ways and
means to squeeze nanoseconds out of some Python bottleneck
that do not necessarily require using local variables where
you need instance or other non-local ones!


> So is there a way to extend methods in the above sense
> or is there a better (more pythonic ? ;-) approach to what I want?

There is no pythonic way to treat local variables as non-local.
(There MAY be horrible bytecode hacks exploiting hooks that are
meant for debugging only -- but THOSE *WILL* slow you down
SERIOUSLY...).


Alex





More information about the Python-list mailing list