Извращение? или таки имеет право быть?
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())