Niech spam
będzie instancją klasy Spam
i przypuśćmy, że spam.ham
jest obiektem typu wbudowanego, na przykład dict
. Mimo że Spam
nie jest podklasą dict
, chciałbym, aby jego instancje miały ten sam interfejs API co zwykły dict
(tj. Te same metody z tymi samymi sygnaturami), ale chcę uniknąć pisania na bazilionowych metodach formularza:Jak zautomatyzować delegowanie __special_methods__ w Pythonie?
def apimethod(self, this, that):
return self.ham.apimethod(this, that)
próbowałem następujące:
class Spam(object):
def __init__(self):
self.ham = dict()
def __getattr__(self, attr):
return getattr(self.ham, attr)
... ale to działa na "zwykłych" metod, jak keys
i items
, ale nie dla metod specjalnych, jak __setitem__
, __getitem__
i __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()
Wszystkie specjalne metody próbowałem produkowane podobnych błędów.
Jak mogę zautomatyzować definicję metod specjalnych (tak aby uzyskać mowa delegata)?
Wyjaśnienie: Niekoniecznie szukam rozwiązań, które wykorzystują standardową sekwencję wyszukiwania metod. Moim celem jest zminimalizowanie kodu standardowego.
Dzięki!
Jestem pewien, że masz dobry powód, ale czy mógłbyś wyjaśnić, dlaczego nie chcesz, aby 'Spam' był podklasą' dyktatu'? – zwol
Urgh. Drugi Zack: jeśli chcesz wyglądać jak "dict", odziedzicz po "dyktorze". – katrielalex