Before I start, I’m already aware that object immutability in Python is often a bad idea, however, I believe that in my case it would be appropriate.
Let’s say I’m working with a coordinate system in my code, such that each coordinate uses a struct of X, Y, Z. I’ve already overloaded subtraction, addition, etc. methods to do what I want. My current problem is the assignment operator, which I’ve read cannot be overloaded. Problem is when I have the following, I do not want A to point to the same point as B, I want the two to be independent, in case I need to overwrite a coordinate of one but not the other later:
B = Point(1,2,3)
A = B
I’m aware that I can use deepcopy, but that seems like a hack, especially since I could have a list of points that I might need to take a slice of (in which case it would again have a slice of point references, not points). I’ve also considered using tuples, but my points have member methods I need, and a very large portion of my code already uses the structs.
My idea was to modify Point to be immutable, since it’s really only 3 floats of data, and from doing some research _new _() seems like the right function to overwrite for this. I’m not sure how to achieve this though, would it be something like this or am I way off?
def __new__(self):
return Point(self.x, self.y, self.z)
EDIT:
My bad, I realized after reading katrielalex’s post that I can’t modify a parameter of immutable object once it has been defined, in which case it’s not a problem that both A and B point to the same data since a reassignment would require creation of a new point. I’d say that katrielalex’s and vonPetrushev’s posts achieve what I want, I think I’ll go with vonPetrushev’s solution since I don’t need to rewrite all my current code to use tuples (the extra set of parentheses and not being able to reference coordinates as point.x)
In conjunction with katrielalex’s suggestion, making the
Pointa named tuple would be good as well. Here I’ve just replaced thetupleparent withnamedtuple('Point', 'x y z')– and that’s enough for it to work.Then you can have:
(Thanks to katrielalex for suggesting to extend the namedtuple rather than copying the code produced.)