Skip to content Skip to sidebar Skip to footer

Python 2.7 - Clean Syntax For Lvalue Modification

It is very common to have struct-like types that are not expected to be modified by distant copyholders. A string is a basic example, but that's an easy case because it's excusably

Solution 1:

In Python, the typical pattern is to copy before modification rather than copying on assignment. You could implement some kind of data store with the semantics you want, but it seems like a lot of work.

Solution 2:

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/classPoint(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)

    defcopy(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', 15print my_very_long_and_complicated_lvalue_expression
# result:# [(11 9), (15 10), (10 10)]

my_very_long_and_complicated_lvalue_expression[1]<<='y', 25print 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 = ..."

Post a Comment for "Python 2.7 - Clean Syntax For Lvalue Modification"