これは可能です...しかし、少し手間がかかります。基本的な考え方は、右シフト演算子を使用して、実際の計算を延期する新しいタイプのオブジェクトを作成および更新することです。
たとえば、上記の変数A、B、C、D、およびEはすべてActual型のオブジェクトであるとします。Actualのインスタンスでrshift操作によって生成される新しいクラスDeferredを紹介します。Deferredは、オブジェクトを更新してそれ自体を返すrshift演算子も実装します。
(ところで、この回答の残りの部分では、A、B、C、D、およびEは不変であり、rshift操作によって新しいオブジェクトが生成されると想定しています。)
F = A >> B >> C >> D >> E
次のように計算されます...
F = Deferred(A,B) >> C >> D >> E
F = Deferred(A,B,C) >> D >> E
F = Deferred(A,B,C,D) >> E
F = Deferred(A,B,C,D,E)
Fは、逆のシーケンスから計算される、Actualのキャッシュされたインスタンスを維持します。さらに、FはActualと同じインターフェースを実装しているため、Deferredのインスタンスで呼び出されたメソッドは、Actualのキャッシュされたインスタンスに委任されます。
あなたが行っている計算の種類がわからないので、次の例では、延期された計算が実際に実行されるときにそれらが逆になることを示すために、ある種の些細なことを構成します。
class Var(object):
def __init__(self):
pass
@property
def name(self):
return self._name( )
@property
def length(self):
return len(self.name)
class Actual(Var):
def __init__(self, name):
Var.__init__(self)
self._text = name
def _name(self):
return self._text
def __rshift__(self, other):
if isinstance(other, Actual):
return Deferred(self, other)
return len(self.name)
@staticmethod
def NewFromShiftComputation(sequence):
x = ' >> '.join(reversed(map(lambda actual: actual.name, sequence)))
return Actual(x)
class Deferred(Var):
def __init__(self, *args):
Var.__init__(self)
self._items = [ ]
self._actual = None #-- cached "actual"
for item in args:
self._items.append(item)
def _name(self):
self._assure_actual( )
return self._actual.name
def __rshift__(self, other):
self._actual = None #-- Invalidate the cached "actual"
self._items.append(other)
return self
def _assure_actual(self):
if self._actual is None:
self._actual = Actual.NewFromShiftComputation(self._items)
A = Actual('A')
B = Actual('B')
C = Actual('C')
D = Actual('D')
E = Actual('E')
F = A >> B >> C >> D >> E
print F.name
print F.length