Is it possible to overload Python assignment?
The way you describe it is absolutely not possible. Assignment to a name is a fundamental feature of Python and no hooks have been provided to change its behavior.
However, assignment to a member in a class instance can be controlled as you want, by overriding .__setattr__()
.
class MyClass(object): def __init__(self, x): self.x = x self._locked = True def __setattr__(self, name, value): if self.__dict__.get("_locked", False) and name == "x": raise AttributeError("MyClass does not allow assignment to .x member") self.__dict__[name] = value>>> m = MyClass(3)>>> m.x3>>> m.x = 4Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 7, in __setattr__AttributeError: MyClass does not allow assignment to .x member
Note that there is a member variable, _locked
, that controls whether the assignment is permitted. You can unlock it to update the value.
I don't think it's possible. The way I see it, assignment to a variable doesn't do anything to the object it previously referred to: it's just that the variable "points" to a different object now.
In [3]: class My(): ...: def __init__(self, id): ...: self.id=id ...: In [4]: a = My(1)In [5]: b = aIn [6]: a = 1In [7]: bOut[7]: <__main__.My instance at 0xb689d14c>In [8]: b.idOut[8]: 1 # the object is unchanged!
However, you can mimic the desired behavior by creating a wrapper object with __setitem__()
or __setattr__()
methods that raise an exception, and keep the "unchangeable" stuff inside.