Reputation: 3
I was recently trying to write and manipulate a class in Python and I came across an odd situation. Whenever I try to manipulate a variable of an instantiation of a class, it only affects the variable in the location where it was change. For example:
class test:
def __init__(self):
self.test1 = 0
self.location = {"test1":self.test1}
self.row = [self.test1]
def change():
a = test() #instantiation
a.location['test1'] = 1 #Changing a.test1 to 1 within a dictionary
print(a.test1) #Print a.test
print(a.location['test1']) #Print a.test1 from within the dictionary where it was changed
print(a.row) #Print a list also containing a.test1
change()
Outputs to:
0 #Variable itself is unchanged
1 #Variable in dictionary is changed
[0] #Same variable referenced in list is unchanged as well
Why does this happen and how could I change a.test1 to equal 1 by only changing it through the dictionary?
Upvotes: 0
Views: 71
Reputation: 1332
When you are assigning the value to the dictionary you are replacing the self.test1
reference. As far as I know there is no way to 'point' to the dictionary value, or store a reference to it. If any one knows otherwise, please enlighten me.
Upvotes: 0
Reputation: 84
Changing what self.location["test1"] is equal to doesn't change the value of self.test1.
class Test:
def __init__(self):
self.test1 = 0
self.location = {"test1":self.test1}
self.row = [self.test1]
def change():
a = test()
a.location['test1'] = a.test1 = 1
a.row = [a.test1]
print(a.test1)
print(a.location['test1'])
print(a.row)
change()
Upvotes: 0
Reputation: 1608
This happens because python integers are immutable. So, every time you do any operation with integer - it's actually creates new object instead of create pointer to prevoius object. This could be easyly illustraded with following code:
>>> a = 0
>>> b = a
>>> b += 1
>>> a, b
(0, 1)
But, if you would use lists, for example, you would get something like this:
>>> a = []
>>> b = a
>>> b.append(1)
>>> a, b
([1], [1])
In summing up - your code work as it should. Also, i suggest you to try following snippet:
class test:
def __init__(self):
self.test1 = [0]
self.location = {"test1": self.test1}
self.row = [self.test1]
def change():
a = test() #instantiation
a.location['test1'][0] = 1 #Changing a.test1 to 1 within a dictionary
print(a.test1) #Print a.test
print(a.location['test1']) #Print a.test1 from within the dictionary where it was changed
print(a.row) #Print a list also containing a.test1
change()
Which would produce you:
[1]
[1]
[[1]]
Upvotes: 1