2

What is the semantic difference in Python regarding these two statements?

    class Person :
        age = 5

and

    class Person :

        def __init__(self):
            self.age = 5

If I do instantiate, in both cases, an object, e.g

    mario = Person ()

In both cases mario's age is 5

So, where is the need of using the __init__ method, if an object is assigned a property as soon as it is instantiated, even without using __init__?

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
A. N. Other
  • 409
  • 4
  • 14

2 Answers2

3

The __init__ attributes refer to a variable of an instance of a class, right under class means it is a class variable.

It will mostly matter when you use for example a list for a variable: right under class will make the list shared between class instantiations, i.e. if you append to that list in one instantiation of the class, all other instantiations of the class will also "see" the appended item in the list.

class Foo:
   x = []

a = Foo()
b = Foo()
a.x.append(1)

b.x == [1] # True

c = Foo()    # Even being created after 1 has been appended, still:
c.x == [1] # True

This is not the case when you use __init__, the "x" attribute will be unique for each instantiation.

PascalVKooten
  • 20,643
  • 17
  • 103
  • 160
2

The difference between the two is that in the above example you are creating a class attribute, while in the init you are creating an instance attribute. The difference between the two is this:

class Foo():
    bob = "my name is bob"

print(Foo.bob)
# outputs "my name is bob"

class Foo():
    def __init__(self):
        self.bob = "my name is bob"

Doing print(Foo.bob):

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: type object 'Foo' has no attribute 'bob'

To access bob in the init you have to instantiate:

f = Foo()
print(f.bob)
# outputs "my name is bob"

What further differentiates the two of these implementations is that the class attribute will be shared among all instances, while instance attributes are shared only within your instance.

So, for anything defined inside your __init__, if you create a new object of Foo, you will not carry any of the changes that you might make to variables inside the init to other instances of Foo.

However, for class attributes, whatever class attribute you change will be changed across all instances of Foo.

idjaw
  • 25,487
  • 7
  • 64
  • 83