0

Why are Dictionaries passed as a reference to classes?

I used to think that when I pass variables to a class, they are copied.

class MyClass:
    def __init__(self, arg=None):
        self.arg = arg

a = 'a'
m1 = MyClass(arg=a)
a = 'b'
print(m1.arg)  # Prints "a"

After using Python for a very long time I just figured out that when I pass a Dictionary, it is not copied, but referenced. So changing the variable afterwards, changes the classes variable. That was very unexpected.

d = {'a': 'a'}
m2 = MyClass(arg=d)
d['a'] = 'b'
print(m2.arg)  # Prints "{'a': 'b'} ... why suddenly 'b'?"

Does this happen only to dictionaries, or are there other types that are referenced? Why is it different anyway?

Daniel
  • 3,092
  • 3
  • 32
  • 49

1 Answers1

1

This all boils down to mutability, since the object is mutable any changes to it won't return a new object but instead alter the existing reference. This change is then seen in all other names that hold a reference to that object.

Dictionaries and lists, two examples of mutable structures, apply here. d['a'] = 'b' mutates the dictionary so that change will be seen in self.arg which holds a reference to it.

Objects such as ints or strs, when operated on, return a new object so, even if you tried performing an operation like:

a += 'b'

which you'd expect mutates the str object and is reflected in self.arg, you'd be disappointed to find out it doesn't, since strings are immutable.

a = 'b' is completely different, it simply makes the name a refer to the string object 'b'; it doesn't try to perform any operation on the existing value referred to by a; try the same statement with a dictionary.

Dimitris Fasarakis Hilliard
  • 150,925
  • 31
  • 268
  • 253