I'm currently trying to code a program using Object-Oriented Programming and I've run into a problem; what I'm trying to do is use a getter to call for a particular attribute of a particular object as a reference so I can assign it to a variable to manipulate the data without affecting the object (similar to how you could say 'x = [1, 2, 3]' then ' y = x' and be able to manipulate y without affecting x.
However, I'm having the problem that (as far as I can tell) the getter is returning the actual attribute itself (i.e. a reference to the attribute) so that any changes to the variable are also performed on the attribute.
Am I missing something or do I just have to alter the getters to first store the attribute as a variable and then return the variable (because I feel like that's a somewhat ham-handed work around)?
As an example of what I'm trying to say, here's a code that should outline the problem: https://repl.it/@lclarkejhdf/Problem-with-getters
Any help is much appreciated!
First off, you've made your question super concise and to the point, good job!
The problem here isn't with your getter returning the wrong thing, it is with lists and mutable objects in general. As you've mentioned in your example, if i did the following
x = [1, 2, 3] y = x
Then I wouldn't be able to change
y without affecting the other. So where you should have started thinking is how you would solve this problem in the first place.
Here, when i say
y = x, what i'm doing is assigning
y to the same object that
x refers to, which isn't of much use because both the variables are now keeping track of the same object.
What I want to do is to make
y contain the same items as
x, but store them both as separate objects. You can do that like this
y = [i for i in x]
or like this
y = [*x]
Both of which essentially create a copy of
x, and store that in
Your workaround wouldnt really work, it would have done the exact same thing if you had stored the attribute in a variable and then returned it. (Which does make sense if you think about it)
Speaking of workarounds, by the way, your implementation of getters and setters sort of is one. How you would do it in Python is by using things called 'decorators'. Here's a good video explaining it.
Let me know if i lost you anywhere, and if i didnt, I'll leave extending this idea into your getter function as an exercise for you ;)
@JustARatherRidi I never realised that doing 'y = x' when x is a list means that both variables refer to the same list, I guess it's true that you learn something everyday!
Also, I don't know why I explained my workaround the way I did, since the workaround I have actually used is what you suggested using (although I have a for loop that appends each item from the original list to a new list, so I think I'll use you method since that's more concise).
As for decorators, I read about them while trying to find out where I might have been going wrong; I feel like I'll try learning them in future since they're apparently a better way of doing it (or at least that's the impression I'm getting), but for now I'll probably stick to what I have been doing since that's how we've been taught in my course so I want to show that I do understand the method taught before going onto more 'advanced' methods.
Thanks for all the help!
y = x does indeed make both the variables point to the same value, and you can even check for it:
- There's the
idfunction, which returns a unique id for every object stored in memory. Call it on both
y, and you'll see that both the variables are actually pointing to that same list.
- There's also the
isoperator, which is quite self-explanatory
>>> x = [1, 2, 3] >>> y = x >>> x is y True >>> x = [1, 2, 3] >>> y = [1, 2, 3] >>> x is y False
Sometimes this stuff can get confusing though, so when you have the time I really recommend this article (15-20 minute read).
You're right about decorators, although they may be the more pythonic way to go about doing things, you should probably stick to your course.
No problem, Cheers!