Typically, the best approach I have found overrides __ilshift__ as a setter and __rlshift__ as a getter, duplicated by a property decorator. This is almost the last statement allowed only (| & ^), and the logical one below. It is rarely used ( __lrshift__ less, but it can be taken into account).
When using the PyPi destination package, only the direct destination can be controlled, so the actual "strength" of the operator is lower. PyPi assign sample package:
class Test: def __init__(self, val, name): self._val = val self._name = name self.named = False def __assign__(self, other): if hasattr(other, 'val'): other = other.val self.set(other) return self def __rassign__(self, other): return self.get() def set(self, val): self._val = val def get(self): if self.named: return self._name return self._val @property def val(self): return self._val x = Test(1, 'x') y = Test(2, 'y') print('x.val =', x.val) print('y.val =', y.val) x = y print('x.val =', x.val) z: int = None z = x print('z =', z) x = 3 y = x print('y.val =', y.val) y.val = 4
output:
x.val = 1 y.val = 2 x.val = 2 z = <__main__.Test object at 0x0000029209DFD978> Traceback (most recent call last): File "E:\packages\pyksp\pyksp\compiler2\simple_test2.py", line 44, in <module> print('y.val =', y.val) AttributeError: 'int' object has no attribute 'val'
Same thing with shift:
class Test: def __init__(self, val, name): self._val = val self._name = name self.named = False def __ilshift__(self, other): if hasattr(other, 'val'): other = other.val self.set(other) return self def __rlshift__(self, other): return self.get() def set(self, val): self._val = val def get(self): if self.named: return self._name return self._val @property def val(self): return self._val x = Test(1, 'x') y = Test(2, 'y') print('x.val =', x.val) print('y.val =', y.val) x <<= y print('x.val =', x.val) z: int = None z <<= x print('z =', z) x <<= 3 y <<= x print('y.val =', y.val) y.val = 4
output:
x.val = 1 y.val = 2 x.val = 2 z = 2 y.val = 3 Traceback (most recent call last): File "E:\packages\pyksp\pyksp\compiler2\simple_test.py", line 45, in <module> y.val = 4 AttributeError: can't set attribute
Thus, <<= operator receiving the value in the property is a much more visually clean solution, and it does not try to force the user to make some reflective errors, such as:
var1.val = 1 var2.val = 2