Today I learned a nice thing about Python. I don't know the specifics, but I was told that this is an intentional design decision in Python.
The thing is: When you declare an object in a class, the class uses a 'pointer' towards that object. (I'm using the word 'pointer' here. The specifics might be a bit different. Be free to elaborate in the comments). This means that if you have two instances of your class and you change one of the object variables, it is also changed in the second instance of your class.
Code example to make things clear:
# Declare a class with two variables class TestObj(object): obj_var = {} # object val_var = 11 # value # Create two instances of the class test_one = TestObj() test_two = TestObj() # Change both variables of one instance test_one.obj_var['key'] = 'value' test_one.val_var = 10 # Print both variables of both instances test_one.val_var Out: 10 # Expected test_two.val_var Out: 11 # Expected test_one.obj_var Out: {'key': 'value'} # Expected test_two.obj_var Out: {'key': 'value'} # Huh?
The solution?
class TestObj(object): val_var = 11 def __init__(self): self.obj_var = {}
Instead of using
__init__
you can of course declare the variable whenever you need it.Update:
You might think it's a bad idea to change class variables on an instance of a class. You are correct, it feels bad and you probably shouldn't be doing things like I did in my example. However, look at the issue still exists when you let the class itself change its variables:
class TestObj(object): obj_var = {} def change_obj_var(self): self.obj_var['hello'] = 'world' test_one = TestObj() test_two = TestObj() test_one.change_obj_var() test_one.obj_var Out: {'hello': 'world'} # Expected test_two.obj_var Out: {'hello': 'world'} # Huh?