automatic delegation

  • Thread starter Hallvard B Furuseth
  • Start date
H

Hallvard B Furuseth

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__().
 
V

Ville Vainio

h.b.furuseth> Is it possible to write a metaclass or something so that
h.b.furuseth> with a class definition not much larger than this:

h.b.furuseth> class foo:
h.b.furuseth> def __init__(self, val): self.val = val

h.b.furuseth> operations on a foo instance f will be applied to f.val?
h.b.furuseth> E.g. str(f) -> f.__str__() -> f.val.__str__().

http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52295
 
P

Peter Otten

Hallvard said:
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__().

I tried in vain to solve your problem while improving my understanding of
metaclasses. I have made an observation that might interest you, though:
str(foo()) and foo.__str__(foo()) are not the same:
.... def __getattribute__(self, name):
.... def tostr(self):
.... return "so what"
.... return tostr
........ __metaclass__ = Type
....
Care to explain, anyone?

Peter
 
Y

Yermat

Hallvard said:
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)

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

Hallvard B Furuseth

Yermat said:
Hallvard said:
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:
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:
'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?

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

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,202
Messages
2,571,057
Members
47,666
Latest member
selsetu

Latest Threads

Top