Locked learning resources

Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Locked learning resources

This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Package Initialization

In this lesson, you’ll learn about package initialization. If a file named __init__.py is present in a package directory, it is invoked when the package or a module in the package is imported. You can use this to execute package initialization code, for example for the initialization of package-level data.

Consider the following __init__.py file:

Python
print(f'Invoking __init__.py for {__name__}')
alist = ['spam', 'bacon', 'eggs']

Add this file to the pkg directory from the above example:

Illustration of hierarchical file structure of Python packages

Now, when the package is imported, the global list alist is initialized:

Python
>>> import pkg
Invoking __init__.py for pkg
>>> pkg.alist
['spam', 'bacon', 'eggs']
>>> pkg.mod1
Traceback (most recent call last):
  File "<input>", line 1, in <module>
    pkg.mod1
AttributeError: module 'pkg' has no attribute 'mod1'

A module in the package can access the global by importing it in turn:

Python
def load_data():
    print('loading data using mod1.load_data()')
    from pkg import alist
    print(f'This is from pkg - {alist}')

class Customer:
    pass

Here’s what you get:

Python
>>> from pkg import mod1
Invoking __init__.py for pkg
>>> mod1.load_data()
loading data using mod1.load_data()
This is from pkg - ['spam', 'bacon', 'eggs']

Revert mod1.py to the previous version by changing load_data() to no longer use the import from pkg:

Python
def load_data():
    print('loading data using mod1.load_data()')

class Customer:
    pass

You can also use __init__.py to effect automatic importing of modules from a package. For example, earlier you saw that the statement import pkg only places the name pkg in the caller’s local symbol table and doesn’t import any modules. Let’s say that __init__.py in the pkg directory contains the following:

Python
print(f'Invoking __init__.py for {__name__}')
import pkg.mod1, pkg.mod2

Then, when you execute import pkg, modules mod1 and mod2 would be imported automatically:

Python
>>> import pkg
Invoking __init__.py for pkg
>>> pkg.mod1.load_data()
loading data using mod1.load_data()
>>> x = pkg.mod2.Location()
>>> x
<pkg.mod2.Location object at 0x10e1c2dd8>

00:00 In this video, you’re going to learn about package initialization. When talking about package initialization, you need to learn about the __init__.py file.

00:11 If a file named __init__.py is present in a package directory, it’s going to be invoked when the package or a module inside that package is imported. The placement for the __init__ file will look like this.

00:23 So, here’s the directory pkg/ (package), and inside of it will be __init__.py, and then the two modules. Let me show you how this works with some code.

00:35 So over here in the EXPLORER, you can see the directory for pkg/, and if I open it up, there’s still mod1.py and mod2.py.

00:43 So what you need to do is create a new file __init__.py inside there. __init__.py. This file can be used to execute package initialization code.

00:58 This might be something that’s specific for package-level data. In this case, let’s make __init__.py have a print() statement to show that it’s been executed,

01:10 and then show its name, again using the __name__ variable that you learned about earlier. And then one other thing you can have in here is a global variable.

01:21 Let’s say there’s a list, and just call it alist,

01:29 and it’s got three strings inside of it. So, here’s __init__.py. __init__.py when imported would run this code, printing out that it’s f'Invoking __init__.py for {__name__}', and then it also assigns this global variable. Okay. So again, here are all the items inside your package.

01:47 From the terminal, start your REPL. What happens when you import pkg now? Well, you’ll actually see something a little different. It will then print this out, and show that it’s imported pkg.

02:01 But also, under pkg you can see that alist is there. Importing pkg imports that __init__ file automatically, executing the code and importing the objects that were part of it.

02:16 Now, the other modules are not here, but here’s something kind of interesting. Go back to mod1.py.

02:27 A module inside the package can access that global list by importing it in turn. This could be imported inside of mod1. To do that, again, you might remember load_data() prints this statement out, but it could also print…

02:54 Printing out that list. Make sure that you save, and then exit and re-enter the REPL.

03:05 What happens if you take from pkg and import simply mod1? A couple of things. One, it’s going to run the code from __init__.py, Invoking __init__.py for pkg.

03:17 And I want to re-stress this, that importing one of the modules also executes the code in __init__.py. Now, mod1 has the load_data() function inside of it, and if you call it, here you can see the two things. It’s printing the first statement, which was loading data using mod1.load_data(), but then it’s also printing the second statement after it’s imported the alist global variable.

03:46 Another use for the __init__.py file is that it can be used to automatically import the modules from a package. Let me show you what that looks like.

03:57 Back inside __init__.py, get rid of the global alist variable. And instead, after it shows that it’s been invoking it with that print() statement, import pkg.mod1, pkg.mod2.

04:11 So here, when executing the code inside of __init__.py, it’s going to import the two modules. So, go ahead and save.

04:24 What happens if you import pkg? It looks like it’s doing the same thing. It is Invoking __init__.py for pkg—it’s printing that out.

04:32 But also, you can see here pkg has these modules available now. It’s imported them, so pkg.mod1 has the Customer class and load_data().

04:44 Now, this might give me an error because I didn’t change mod1 back. It can’t find the alist from pkg, so I need to change that.

04:54 Back inside mod1, go ahead and delete this line,

05:01 and save.

05:06 Now exit and restart the REPL one more time. So here we go. import pkg, and then you can see pkg.mod1.load_data(). Again, no issues because it’s just printing that out.

05:18 You could make an object using pkg.mod2. Create a Location. So, x is using that. You can see that import pkg with that __init__ code of it importing pkg.mod1 and pkg.mod2, it’s importing both modules automatically.

05:38 In the next video, I’ll show you about importing using the wildcard asterisk (*) from a package.

Avatar image for jeffwashcloth

jeffwashcloth on May 13, 2020

What is the environment used in these videos? It’s pretty nifty, with its own file explorer, interpreter, and editor.

Avatar image for Chris Bailey

Chris Bailey RP Team on May 13, 2020

Hi @jeffwashcloth, I’m using VSCode. Here is a course on setting it up.

Avatar image for jeffwashcloth

jeffwashcloth on May 13, 2020

Great, thanks for the info

Avatar image for srisaisousar

srisaisousar on July 8, 2020

init.py file is not executed in python 3.8.2 Why ?

Avatar image for Andy Pickett

Andy Pickett on Feb. 23, 2021

Great tutorial Chris. I found RealPython through the podcasts which, again are fantastic so thanks!

I’m sitting here laughing at myself as Dunder has been one of my revision topics for the last few days. I couldn’t seem to retain what they were and how they are used. (Still some work to go) …but when my brain suddenly realised that Dunder must mean DoubleUNDERscore it all became clear. Strangely nothing I’ve read so far had mentioned that and yet it seems like such a good way of anchoring them.

Hope this is useful to anyone else trying to learn them too!

Become a Member to join the conversation.