0
class Number():
    list = []

number = Number()
number.list.append(0)
print number.list  # [0]

newNumber = Number()
newNumber.list.append(1)
print newNumber.list  # [0,1]

I have created two instance, why the newNumber.list object has the 0? Why the number and the newNumber use the same list? Anybody can help me? and Why the 'i' is not change in the follow?

class Number:
i = 0

number = Number()
number.i = 1
print number.i  # 1

newNumber = Number()
print newNumber.i  # 0
Lei Kan
  • 487
  • 7
  • 20
  • you must use self.list i think. see this question for self keyword: http://stackoverflow.com/questions/6990099/explaining-the-python-self-variable-to-a-beginner – Barış Akkurt Apr 27 '13 at 16:15
  • 4
    because `list` as defined in your code belongs to the `class` not the instances. you need to write `self.list = []` to have one `list` per instance – behzad.nouri Apr 27 '13 at 16:16

1 Answers1

11

That's because you created the list as a member of the class object, rather than the instance objects. If you want to create a seperate list for each instance, you need to do something like this (I changed list to list_ since it's bad practice to give variables the same name as builtins).

class Number():
    def __init__(self):
        self.list_ = []

When you access an attribute on an object, it first checks the instance dictionary and then the class object dictionary. That's why making it a member of the class object didn't give you any errors. But since it's only a single list, every object will access that same list.

Antimony
  • 37,781
  • 10
  • 100
  • 107
  • Why is having members with the same name as builtins a problem? – Eric Apr 27 '13 at 16:26
  • 3
    @Eric, then how would you know what `number.list` means? It could be a plain property which stores some list, but it could also be the `list` type (constructor), for example I could do `number.list('abc')`. – Cristian Ciupitu Apr 27 '13 at 16:37
  • 1
    It doesn't directly cause a problem like it would with local or global variables, but it does make things more confusing. – Antimony Apr 27 '13 at 17:13
  • Why would I ever expect to have a member of my class be the `list` object? I see no reason to expect `a.list` to be in any way related to `list` – Eric Apr 27 '13 at 18:31
  • `class Number: i = 0 number = Number() number.i = 1 print number.i # 1 newNumber = Number() print newNumber.i # 0` why the newNumber.i is not 1? – Lei Kan Apr 28 '13 at 01:13
  • Because you're assigning the new value `1` to the instance dictionary of `number`, not the class dictionary. You can see which is in which by examining `number.__dict__` and `Number.__dict__`. The reason the list showed the changes is because you were mutating the existing, shared list. But when you assign an attribute of `number`, it goes in the instance dictionary. To set it in the class dictionary, you'd have to do `Number.i = 1`. Or `number.__class__.i = 1`. – Antimony Apr 28 '13 at 02:01