Operator overloading and __getattr__

Bengt Richter bokr at oz.net
Wed Dec 24 15:42:54 EST 2003


On Tue, 23 Dec 2003 11:22:28 -0500, "John Roth" <newsgroups at jhrothjr.com> wrote:

>
>"Samuel Kleiner" <sam at h41n2fls31o839.telia.com> wrote in message
>news:slrnbue5dp.72h.sam at h41n2fls31o839.telia.com...
>> I'm trying to create methods on method access- but __getattr__ fails
>> with operator overloading(below) Any suggestions? EG:
>
>I haven't a clue what you're trying to do, but
>I believe it's not possible to install "magic methods"
>after the class is defined. Nor can you install
>them in the instance. They'll look like they've
>been installed, but the interpreter will never
>execute them because it does not look there
>for them. It looks in special places in the C
>language structure for the class definition.
>
I'm not sure what you mean about not installing methods, but methods
are effectively dynamically created when you access functions via a
class attribute name, so you can tack them on any time before you
access them. If you access them via a class attribute per se, you get
an unbound method, and if you access them via a class instance, you get
a bound (to that instance) method. E.g.,

 >>> class A(object): pass
 ...
 >>> class B(object): pass
 ...
 >>> a=A(); b=B()
 >>> def method_name(self): return 'This is from a method of %s'% self.__class__.__name__
 ...
 >>> A.foo = B.foo = method_name
 >>> A.foo
 <unbound method A.method_name>
 >>> B.foo
 <unbound method B.method_name>
 >>> a.foo
 <bound method A.method_name of <__main__.A object at 0x009023B0>>
 >>> b.foo
 <bound method B.method_name of <__main__.B object at 0x00902050>>
 >>> a.foo()
 'This is from a method of A'
 >>> b.foo()
 'This is from a method of B'

Note the distiction between 'foo' and 'method_name'. Once 'foo' has been used to
create the method, only the name of the function is available via the (un)bound method
object reference. They happen to match when you do the def inside the class scope, but
they don't have to, though the repr string might be a little confusing when they don't.

If you use a programming trick to get the function bound as an attribute of a class,
that should work just like doing it explicitly as above.

Note that the unbound method is not just a reference to the function:

 >>> A.foo(a)
 'This is from a method of A'
 >>> A.foo(b)
 Traceback (most recent call last):
   File "<stdin>", line 1, in ?
 TypeError: unbound method method_name() must be called with A instance as first argument (got B
 instance instead)

Though you can sneak around to it:

 >>> A.foo.im_func
 <function method_name at 0x008FDE70>

And it happens to work as a function
 >>> A.foo.im_func(b)
 'This is from a method of B'

To get that function we see via A to be an unbound method of B is also possible:

 >>> A.foo.im_func.__get__(None, B)
 <unbound method B.method_name>
 >>> A.foo.im_func.__get__(None, B)(b)
 'This is from a method of B'
 >>> A.foo.im_func.__get__(None, B)(a)
 Traceback (most recent call last):
   File "<stdin>", line 1, in ?
 TypeError: unbound method method_name() must be called with B instance as first argument (got A
 instance instead)

Regards,
Bengt Richter




More information about the Python-list mailing list