__init__ explanation please

Fredrik Lundh fredrik at pythonware.com
Sun Jan 13 07:44:58 EST 2008


Erik Lind wrote:

> I'm new to Python, and OOP. I've read most of Mark Lutz's book and more 
> online and can write simple modules, but I still don't get when __init__ 
> needs to be used as opposed to creating a class instance by assignment.

nothing is ever created by plain assignment in Python; to create a class 
instance in Python, you *call* the class object.  an example:

    class MyClass:
        pass

    # create three separate instances
    obj1 = MyClass()
    obj2 = MyClass()
    obj3 = MyClass()

(it's the () that creates the object, not the =)

if you want to initialize the method's state (that is, set some 
attributes), you can do that from the outside:

    obj1.attrib = "some value"

or in an "initialization" method in the class:

    class MyClass:
        def init(self):
            self.attrib = "some value"

    obj1 = MyClass()
    obj1.init()

but in both cases, you'll end up with an inconsistent object state (in 
this case, no attribute named "attrib") if you forget to do this.

    obj1 = MyClass()
    print obj1.attrib # this will fail

to avoid such mistakes, you can use __init__ instead.  this is just a 
initialization method that's automatically called by Python *after* the 
object is created, but *before* the call to the class object returns.

     class MyClass:
         def __init__(self):
             self.attrib = "some value"

     obj1 = MyClass()
     print obj1.attrib # this will succeed

also, any arguments that you pass to the class object call are passed on 
to the initialization method.

     class MyClass:
         def __init__(self, value):
             self.attrib = value

     obj1 = MyClass("hello")
     print obj1.attrib # prints "hello"

as Jeroen points out, this is pretty much the same thing as a 
constructor in other languages -- that is, a piece of code that's 
responsible for setting up an object's state.

Python's a bit different; the object is in fact created before the
call to __init__, but this doesn't matter much in practice; if 
construction fails, the assignment will fail, so the object will be 
lost, and is reclaimed by the GC later on.

(unless you explicitly store a reference to the object somewhere else, 
of course:

 >>> class MyClass:
...     def __init__(self):
...         global secret
...         secret = self
...         raise ValueError("oops! failed!")
...     def method(self):
...         print "here I am!"
...

 >>> obj = MyClass()
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
   File "<stdin>", line 5, in __init__
ValueError: oops! failed!

 >>> obj
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
NameError: name 'obj' is not defined

 >>> secret.method()
here I am!

)

finally, if you want full control also over the actual creation of the 
object, more recent Python versions support a __new__ method that can be 
used instead of __init__, or as a complement.  but that's an advanced 
topic, and is nothing you need to worry about while trying to the hang 
of class basics.

hope this helps!

</F>




More information about the Python-list mailing list