I have a class called Cell:
class Cell:def __init__(self, value, color, size):self._value = valueself._color = colorself._size = size# and other methods...
Cell._value
will store a string, integer, etc. (whatever I am using that object for). I want all default methods that would normally use the "value" of an object to use <Cell object>._value
so that I can do:
>>> c1 = Cell(7, "blue", (5,10))
>>> c2 = Cell(8, "red", (10, 12))
>>> print c1 + c2
15>>> c3 = Cell(["ab", "cd"], "yellow", (50, 50))
>>> print len(c3), c3
2 ['ab', 'cd']# etc.
I could override all the default methods:
class Cell:def __init__(self, value, color, size):# ...def __repr__(self):return repr(self._value)def __str__(self):return str(self._value)def __getitem__(self, key):return self._value[key]def __len__(self):return len(self._value)# etc.
...but is there an easier way?
If I understand you correctly, you're looking for an easy way to delegate an object's method to a property of that object?
You can avoid some of the repetitiveness by defining a decorator:
def delegate(method, prop):def decorate(cls):setattr(cls, method,lambda self, *args, **kwargs:getattr(getattr(self, prop), method)(*args, **kwargs))return clsreturn decorate
You can then apply the decorator for each method you want delegated:
@delegate('__len__', '_content')
@delegate('__getitem__', '_content')
class MyList(object):def __init__(self, content):self._content = contentspam = MyList([1,2,3,4,5])len(spam) # prints "5"spam[0] # prints "1"
You could probably simplify it further by modifying the decorator to take multiple method names as argument.
If you want your class to act as a full wrapper, you could probably override the class's __getattr__
method to check the wrapped object before failing. That would emulate the behaviour of subclasses without actual inheritance.