Lasciare spam
essere un'istanza di qualche classe Spam
e supporre che spam.ham
sia un oggetto di un tipo predefinito, ad esempio dict
. Anche se Spam
non è una sottoclasse di dict
, vorrei le sue istanze avere la stessa API come una normale dict
(cioè gli stessi metodi con le stesse firme), ma voglio evitare di scrivere fuori un metodi bazillion boilerplate della forma:Come automatizzare la delega di __special_methods__ in Python?
def apimethod(self, this, that):
return self.ham.apimethod(this, that)
ho provato la seguente:
class Spam(object):
def __init__(self):
self.ham = dict()
def __getattr__(self, attr):
return getattr(self.ham, attr)
... ma funziona per i metodi "normali", come keys
e items
, ma non per metodi speciali, come __setitem__
, __getitem__
, e __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()
Tutti i metodi speciali che ho provato hanno prodotto errori simili.
Come posso automatizzare la definizione di metodi speciali (in modo da ottenere di cui il delegato)?
Precisazione: non sono necessariamente alla ricerca di soluzioni che sfruttino la sequenza di ricerca del metodo standard. Il mio obiettivo qui è di ridurre al minimo il codice di caldaia.
Grazie!
Sono sicuro che hai una buona ragione, ma potresti spiegare per favore perché non vuoi rendere 'Spam' una sottoclasse di' dict'? – zwol
Urgh. Secondo Zack: se vuoi apparire come un "dict", allora erediti da "dict". – katrielalex