Python the Hard Way -- Lesson 40 question


I’m on Exercise 40 of “Learn Python the Hard Way” reading the HTML book text about Classes and Objects.

The mid-page discussion describes the need to include an init function to create a Class. The book text uses the example below:

class MyStuff(object):

    def __init__(self):
        self.tangerine = "And now a thousand years between"

    def apple(self):
        print("I AM CLASSY APPLES!")

I’m confused about the role the __init_function plays in the creation of Classes and Objects. Clearly, the use of the self_tangerine variable and the lyric as a string assignment is just a random example to demonstrate init.

Yet it seems the existence of an init function of some kind is necessary to enable code to create any object from the class. The book text says as much in its step-by-step description under the “Objects are like Import” sub-head, where it says: “Python then looks to see if you made a “magic” init function, and if you have it calls that function to initialize your newly created empty object.”

In general, how does a programmer decide how to write the init function code? It seems anything would work, as long as it exists. That leaves an infinite number of possibilities – unless I’m completely confused and I may well be!


The 3 lines of code under “Objects are like Imports” have line numbers 1, 2 and 3. As a complete beginner, that confused me since it seemed like they represent a new .py file – like the other files I’ve been typing into my Atom text editor exercise by exercise. But in this case, these lines need to go underneath the class MyStuff(object) code above, so the line numbers would really be something like 10, 11, 12, etc.

Yes, you actually have it right. The only purpose of the __init__ function is to initialize a newly created object before you get it and assign it to a variable. Take a look at this code:

thing = MyStuff()

With the __init__ your thing.tangerine (aka self.tangerine) is setup already to go, because calling MyStuff() does this:

  1. Create a base empty object of type MyStuff.
  2. Call __init__ with this empty object as self.
  3. The __init__ runs and sets up self so it’s ready to go.
  4. Return the newly created object so it can be assigned to thing.

Without that function you’d have to constantly do this:

thing = MyStuff()
thing.tangerine = "Some new lyrics."

Which is both a lot of work, AND something you’d have to constantly get right all the time after every time you made a new MyStuff object. It’s better to put that setup code in the init and let it live in one place.

And, for the “Objects are like Imports”, the key word is like, not imports. When you call MyStuff() it’s creating a new thing. When you import a module, it’s also creating a new thing. The difference then is that with a module you just get one thing, but with MyStuff() you can make as many as you want.

You should also compare that code under the class to the code in a module. It’s pretty similar, just with some shuffling of the . and what you use as a self and where it goes.