OnyxDelta
OnyxDelta

Reputation: 3

In Python, why does the dictonary value of a variable in a class change, while not the variable itself?

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

Answers (3)

0TTT0
0TTT0

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

Fibo36
Fibo36

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

Yaroslav Surzhikov
Yaroslav Surzhikov

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

Related Questions