Python operator overload and associative associativity

I am writing a python program in which I need to overload the → operator. The problem I am facing is that this operator must be the correct associative. Therefore, if I do the following

A >> B >> C >> D >> E

I want this to be parsed as

(A >> (B >> (C >> (D >> E))))

From what I understand in python, this operator is left associative, and so I would get,

((((A >> B) >> C) >> D) >> E)

Do I need to change the default associativity of a statement in python when overloading a statement?

+3
source share
2 answers

... . , , .

, , : A, B, C, D E - Actual. Deferred, rshift Actual. rshift, .

(BTW, , 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
+2

All Articles