[Tutor] [Fwd: Re: Intercepting methods calls]

Marilyn Davis marilyn at deliberate.com
Sat Jun 7 01:27:23 CEST 2008


On Fri, June 6, 2008 3:37 pm, Andreas Kostyrka wrote:

> On Friday 06 June 2008 18:19:23 you wrote:
>
>> On Thu, June 5, 2008 9:39 am, Andreas Kostyrka wrote:
>>
>>> On Thursday 05 June 2008 00:18:55 Marilyn Davis wrote:
>>>
>>>> You listed __init__ and I'm not sure I know what you mean.
>>>>
>>>
>>> Well, __init__ can assign attributes to the instance that are
>>> callable.
>>
>> Oh, well, Python is such a wide-open system.   It keeps blowing my
>> mind.
>
> Well, there is basically nothing that you cannot force the object system
> of Python to do, almost.
>
> E.g. transplanting methods from class A to class B:
>
>
> B.__dict__["method"] = A.__dict__["method"]

Oh dear.

>
>
> Or deriving a class from itself (although a better name would be "from a
> class that happened to be named the same).
>
> class A: pass class A(A): pass print A.__bases__

Oh dear.

>
> Now, as an observation, you will notice that most experienced Python
> developers usually stay away from all this "magic" stuff. Rules of thumb
> include "explicit is good, implicit is bad", and so on. Clearly stuff
> tagged as "you really should know what you are doing".
>
>>
>> I'm thinking that if you can provide an __init__ you can intercept
>> methods the regular way, by providing them the regular way, and
>> overriding them.
>
> Nope, I mentioned it, because this has been way back, when Python was
> young and slow, this was a technique to speed up method lookup.
>
> Actually, it seems to work with py2.5 too, for oldstyle classes:
>
>
> andreas at andi-lap:~/Videos$ python -m timeit -s 'class A:' -s '   def
> m(self): pass'
> 10000000 loops, best of 3: 0.0675 usec per loop
> andreas at andi-lap:~/Videos$ python -m timeit -s 'class A:' -s '   def
> m(self): pass' -s 'a=A()' 'a.m()'
> 1000000 loops, best of 3: 0.747 usec per loop
> andreas at andi-lap:~/Videos$ python -m timeit -s 'class A:' -s '   def
> m(self): pass' -s 'a=A()' -s 'a.m=a.m' 'a.m()'
> 1000000 loops, best of 3: 0.575 usec per loop

Wow.

> andreas at andi-lap:~/Videos$ python -m timeit -s 'class A(object):' -s '
> def m(self): pass' -s 'a=A()' 'a.m()' 1000000 loops, best of 3: 0.671 usec
> per loop andreas at andi-lap:~/Videos$ python -m timeit -s 'class A(object):'
> -s '   def m(self): pass' -s 'a=A()' -s 'a.m=a.m' 'a.m()'
> 1000000 loops, best of 3: 0.641 usec per loop
>
>
> The reason for this is, that the instance dictionary is the first place
> that Python looks when looking for a.m.

I see.  Well, that is interesting.  I'm glad I asked.

>
>>
>> Thank you Andreas.  This has been really interesting and instructive.
>>
>
> Yeah, but please consider my comment. I think every developer should
> have seen the possibilities, but in most cases forget about that ugly
> stuff. You will get a headache, especially if you try to use the full
> "power" that Python provides. One can usually be quite productive without
> relying on these mechanisms.

Yes, and if you consider the poor readers of your code, and/or if speed
isn't so critical, it would be best to forget it.  But, thank you for
showing this to me.

Do you have anything else really interesting to share?

Marilyn Davis

>
> Andreas




More information about the Tutor mailing list