Як правило, найкращий підхід, який я знайшов, це перевизначення __ilshift__
як сеттера та __rlshift__
як геттера, що дублюється декоратором властивостей. Це майже останній оператор, який розв'язується лише (| & ^), а логічні нижче. Він використовується рідко ( __lrshift__
менше, але це можна врахувати).
При використанні пакету присвоєння PyPi можна контролювати лише пряме присвоєння, тому фактична "сила" оператора нижча. Приклад призначення пакету PyPi:
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
вихід:
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'
Те саме зі зміною:
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
вихід:
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
Отже, <<=
оператор, який отримує значення властивості, є набагато більш візуально чистим рішенням, і він не намагається зробити користувачеві деякі відображаючі помилки, такі як:
var1.val = 1
var2.val = 2
var1.val = var2
var1.val = var2.val
somevar = var1 + var2
var1 += var2
var1 = var2