¿Una forma sencilla de anular los métodos predeterminados en las clases personalizadas de Python?

Tengo una clase llamada celular:

class Cell: def __init__(self, value, color, size): self._value = value self._color = color self._size = size # and other methods... 

Cell._value almacenará una cadena, un entero, etc. (para lo que esté usando ese objeto). Quiero que todos los métodos predeterminados que normalmente usarían el “valor” de un objeto usen el valor de ._value para que pueda hacer:

 >>> 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. 

Podría anular todos los métodos predeterminados:

 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. 

… pero hay una manera más fácil?

Si te entiendo correctamente, ¿estás buscando una manera fácil de delegar el método de un objeto a una propiedad de ese objeto?

Puedes evitar algo de la repetitividad definiendo un decorador:

 def delegate(method, prop): def decorate(cls): setattr(cls, method, lambda self, *args, **kwargs: getattr(getattr(self, prop), method)(*args, **kwargs)) return cls return decorate 

Luego puede aplicar el decorador para cada método que quiera delegar:

 @delegate('__len__', '_content') @delegate('__getitem__', '_content') class MyList(object): def __init__(self, content): self._content = content spam = MyList([1,2,3,4,5]) len(spam) # prints "5" spam[0] # prints "1" 

Probablemente podría simplificarlo aún más modificando el decorador para que tome varios nombres de métodos como argumento.

Si desea que su clase actúe como una envoltura completa, probablemente podría anular el método __getattr__ la clase para verificar el objeto envuelto antes de fallar. Eso emularía el comportamiento de las subclases sin herencia real.

__add__ sobrecargar el método __add__ para obtener el comportamiento c1 + c2 que desea.

Consulte aquí para obtener información sobre lo que son todos.