1

I am a little bit confused by this example:

>>> class A:
...     foo = []
>>> a, b = A(), A()
>>> a
<__main__.A instance at 0x0000000002296A88>
>>> b
<__main__.A instance at 0x0000000002296F88>
>>> a.foo.append(5)
>>> a.foo
[5]
>>> b.foo
[5]

1) How does python connect two different instances?

2) Does the instance refer to a class A() or foo attribute after appending the value?

But when i add __init__ method, things look different:

>>> class A:
...     def __init__(self):
...             self.foo = []
...
>>> a, b = A(), A()
>>> a
<__main__.A instance at 0x00000000021EC508>
>>> b
<__main__.A instance at 0x0000000002296F88>
>>> a.foo.append(5)
>>> a.foo
[5]
>>> b.foo
[]

3) What is the magic of __init__ ?

izdi
  • 555
  • 1
  • 7
  • 24

2 Answers2

2

In the first case, the foo = [] is done at class definition time, and thus a single list is associated with the class, rather than the instance.

In the second case, the self.foo = [] is done at instance initialization time (which is what __init__ is - instance initialization), and thus a separate list is associated with each instance.

Amber
  • 507,862
  • 82
  • 626
  • 550
1

In your first example, foo is a class attribute, not an instance attribute. This means it's shared across all the instances of A, which you can check with:

a1 = A()
a2 = A()
print a1.foo is a2.foo
print a1.foo is A.foo

In your second example, however, self.foo = [] makes foo an instance attribute, built independently for each instance of A.

Max Noel
  • 8,810
  • 1
  • 27
  • 35