from abc import abstractmethod
class Base:
@abstractmethod
def exec(self):
pass
def __repr__(self):
vars = self.__class__.__init__.__code__.co_varnames[1:]
values = ', '.join(f'{v}={getattr(self, v)!r}' for v in vars)
return f'{self.__class__.__name__}({values})={self.value!r}'
class Const(Base):
def __init__(self, value):
""" в подклассах Base в __ините__ сохраняй
соответствие имён типа `foo` -> self.`foo` """
self.value = value.exec() if isinstance(value, Base) else value
def exec(self):
return self.value
class Sum(Base):
def __init__(self, *args):
""" почти всё здесь и сейчас """
self.args = tuple(v.exec() if isinstance(v, Base) else v for v in args)
self.value = 0
def exec(self):
self.value = sum(self.args)
return self.value
class DeferredSum(Base):
def __init__(self, *args):
""" почти всё потом когда-нибудь """
self.args = args
self.value = 0
def exec(self):
self.args = tuple(v.exec() if isinstance(v, Base) else v for v in self.args)
self.value = sum(self.args)
return self.value
three = Const(3)
seven = Const(7)
print('three =', three, '\nseven =', seven)
fifteen = Sum(three, 5, seven)
print('\nbefore', fifteen)
print(fifteen.exec())
print('after ', fifteen)
n42 = DeferredSum(27, fifteen)
print('\nbefore', n42)
print(n42.exec())
print('after ', n42)
cls(cls.__name__) # отсылка к def __init__(self, name): self._name = name
думаю можно рассчитывать на O(log(n)) с учетом небходимых периодических аллокаций