automatic delegation

Hallvard B Furuseth h.b.furuseth at usit.uio.no
Wed Aug 4 04:14:14 EDT 2004


Yermat wrote:
>Hallvard B Furuseth wrote:
>> Is it possible to write a metaclass or something so that
>> with a class definition not much larger than this:
>> 
>>    class foo:
>>       def __init__(self, val): self.val = val
>> 
>> operations on a foo instance f will be applied to f.val?
>> E.g. str(f) -> f.__str__() -> f.val.__str__().
> 
> Here a simple example :
> 
> class proxy(object):
>      def __init__(self, obj):
>          self.obj = obj
> 
>      def __getattr__(self, key):
>          if key in self.__dict__:
>              return self.__dict__[key]
>          else:
>              return getattr(self.obj, key)

I tried __getattr__ before I posted, but it doesn't work:

    >>> int(proxy(5))
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
    TypeError: int() argument must be a string or a number

However, the example in the Cookbook works.  Thanks, Ville.
Turns out the above example also works if one one removes 'object'
and makes it and old-style class:

    >>> int(proxy(5))
    5
    >>> str(proxy(5))
    '5'

Seems that with new-style classes, __getattr__ only works for instance
variables, while for old-style classes, it also works for class
variables like __int__ and __str__.  But I can't see anything in the
documentation which says so?

> You can also look at:
> http://www.python.org/cgi-bin/moinmoin/ProxyProgramming

That example doesn't work at all.  The initialization of self._subject
in __init__() breaks because of the definition of __setattr__.

-- 
Hallvard



More information about the Python-list mailing list