I feel like we’ve given the search for pre-existing solutions its due diligence. Given that “<=” is assignment in some languages (e.g., Verilog) we can quite intuitively introduce:
value_struct_instance<<='field', value
as the Pythonic form of
value_struct_instance.field = value
Here is an updated example for instructive purposes:
# Python doesn't support copy-on-assignment, so we must use an
# immutable object to avoid unintended changes by distant copyholders.
# As a consequence, the lvalue must be changed on a field update.
#
# Currently the only known syntax for updating a field on such an
# object is:
#
# value_struct_instance<<='field', value
#
# https://stackoverflow.com/questions/45788271/
class Point(object):
def __init__(self, x, y, others=None):
object.__setattr__(self, 'x', x)
object.__setattr__(self, 'y', y)
def __setattr__(self, name, value):
raise AttributeError, \
"Use \"point<<='%s', ...\" instead of \"point.%s = ...\"" \
% (name, name)
def __repr__(self):
return "(%d %d)" % (self.x, self.y)
def copy(self, x=None, y=None):
if x == None: x = self.x
if y == None: y = self.y
return Point(x, y)
def __ilshift__(a,b):
if b[0] == 'x': return a.copy(x=b[1])
elif b[0] == 'y': return a.copy(y=b[1])
else: raise AttributeError, \
"Point has no member '%s'" % b[0]
def __eq__ (a,b): return a.x == b.x and a.y == b.y
def __ne__ (a,b): return a.x != b.x or a.y != b.y
def __add__(a,b): return Point(a.x+b.x, a.y+b.y)
def __sub__(a,b): return Point(a.x-b.x, a.y-b.y)
my_very_long_and_complicated_lvalue_expression = [Point(10,10)] * 3
# modify element 0 via "+="
my_very_long_and_complicated_lvalue_expression[0] += Point(1,-1)
# modify element 1 via "<<='field'," (NEW IDIOM)
my_very_long_and_complicated_lvalue_expression[1]<<='x', 15
print my_very_long_and_complicated_lvalue_expression
# result:
# [(11 9), (15 10), (10 10)]
my_very_long_and_complicated_lvalue_expression[1]<<='y', 25
print my_very_long_and_complicated_lvalue_expression
# result:
# [(11 9), (15 25), (10 10)]
# Attempt to modify element 2 via ".field="
my_very_long_and_complicated_lvalue_expression[2].y = 25
# result:
# AttributeError: Use "point<<='y', ..." instead of "point.y = ..."
4
solved Python 2.7 – clean syntax for lvalue modification