Sea spam
una instancia de alguna clase Spam
, y suponga que spam.ham
es un objeto de algún tipo incorporado, digamos dict
. Aunque Spam
no es una subclase de dict
, me gustaría que sus instancias tuvieran la misma API que un dict
normal (es decir, los mismos métodos con las mismas firmas), pero quiero evitar escribir un número repetitivo de los métodos del formulario:¿Cómo automatizar la delegación de __special_methods__ en Python?
def apimethod(self, this, that):
return self.ham.apimethod(this, that)
he intentado lo siguiente:
class Spam(object):
def __init__(self):
self.ham = dict()
def __getattr__(self, attr):
return getattr(self.ham, attr)
... pero funciona para métodos "normales", como keys
y items
, pero no para métodos especiales, como __setitem__
, __getitem__
, y __len__
:
>>> spam = Spam()
>>> spam.keys()
[]
>>> spam['eggs'] = 42
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'Spam' object does not support item assignment
>>> spam.ham['eggs'] = 42
>>> foo.items()
[('eggs', 42)]
>>> spam['eggs']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'Spam' object is not subscritable
>>> len(spam)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'Spam' object has no len()
Todos los métodos especiales que probé producen errores similares.
Cómo puedo automatizar la definición de métodos especiales (de modo que consigan que se refiere el delegado)?
Aclaración: No necesariamente estoy buscando soluciones que aprovechen la secuencia de búsqueda de métodos estándar. Mi objetivo aquí es minimizar el código repetitivo.
Gracias!
Estoy seguro de que tienes una buena razón, pero ¿podrías explicar por qué no quieres que 'Spam' sea una subclase de' dict'? – zwol
Urgh. Segundo Zack: si quieres parecer un 'dict' entonces hereda de' dict'. – katrielalex