Форум сайта python.su
Извращение? или таки имеет право быть?
from StringIO import StringIO from unittest import TestCase class MetaChained(type): _instances = {} def __new__(cls, name, bases, dct): new_cls = super(MetaChained, cls).__new__(cls, name, bases, dct) cls._instances[name] = new_cls return new_cls class Chained(object): __metaclass__ = MetaChained value = 'Chained' def __init__(self): self._chained = None def _add_in_chain(self, next): if self._chained: self._chained._add_in_chain(next) else: self._chained = next def __call__(self, out): out.write(self.value) if self._chained: self._chained(out) def __getattribute__(self, item): try: return super(Chained, self).__getattribute__(item) except AttributeError, e: dct = self.__metaclass__._instances if item in dct: def constructor(*args, **kwargs): obj = dct[item](*args, **kwargs) self._add_in_chain(obj) return self return constructor else: raise e class chainedA(Chained): value = 'A' class chainedB(Chained): value = 'B' class chainedC(Chained): value = 'C' class TestChained(TestCase): def test_chained(self): out = StringIO() chain = chainedA().chainedB().chainedC() chain(out) self.assertEqual('ABC', out.getvalue())
Офлайн
Странная штука. Применить visitor к цепочке объектов можно и более простыми способами.
Офлайн
Андрей СветловСобственно всю бодягу разводил ради вот такого синтаксиса построения цепочки.
Странная штука. Применить visitor к цепочке объектов можно и более простыми способами.
chain = chainedA().chainedB().chainedC()
chain = chainedA(chainedB(chainedC()))
Офлайн
Chain(A(), B(), C())(out)
Это в Лиспе всё — списки. Для Питона такое не обязательно.
Офлайн
Мда, уж. На каждого мудреца довольно простаты :) По идеи это
Андрей Светловпервое, что должно прийти в голову, но почему-то не пришло :(
Chain(A(), B(), C())(out)
Офлайн