Creating Modules

We’ll use a straight-forward approach.

  • create a folder m (m from main) and open it
  • create 2 files: hello.py and main.py inside m folder

    #
    # hello.py file
    def f():
        print('hello')
    
    #
    # main.py file
    import hello
    hello.f()
    
  • run main.py ( write python3 main.py in the command prompt ); you will see a hello on the screen

There will come a time when you will work with a lot of functions and you will need to create your libraries. To do this, your functions will be organized in files which will be organized in folders.

Let’s start with creating a folder my_library inside our m folder. Then, move hello.py in my_library. Your file structure should look like:

.
├── main.py
└── my_library
    └── hello.py

By running main.py you will get an error, because the hello module cannot be seen any longer. We should update it:

#
# main.py file
import my_library.hello as hello
hello.f()

This can also work, but it is more verbose:

#
# main.py file
import my_library.hello 
my_library.hello.f()

Now, let’s suppose we want to write it simple: f(). Can we do that? Of course we can.

#
# main.py file
from my_library.hello import *
f()

You will have more than 1 file in your library. You cannot do this if you want your library users to use more functions located in more subdirectories. They will need to do something like:

#
# main.py file
from my_library.hello import * # for f
from my_library.hello2 import * # for g
from my_library.hello90 import * # for ...
f()
g()
dont_do_this()

You should always create a __init__.py inside your library folder, and also in the subfolders of your library.

.
├── main.py
└── my_library
    ├── hello.py
    └── __init__.py

You should write in __init__.py what you want to import, this meaning everything in your library. At this point you should have:

#
# __init__.py file
from . import hello
#
# main.py file
from my_library import *
hello.f()

By running main.py you should see the hello message. What happens if you really want to import every function? Here come some glitches. Let’s see why.

#
# __init__.py file
from .hello import *
#
# main.py file
from my_library import *
f()

This will work! BUT

#
# __init__.py file
from .hello import *
#
# main.py file
from my_library import *
hello.f()	# just this line have changed

will also work.

This:

#
# main.py file
from my_library import *
hello.f()
f()

would print two hello messages.

And this:

#
# main.py file
from my_library import *
hello = 1
f()

will work fine! The module was not touched. This way we can import really everything.

At this point you should be convinced that creating a python library requires a well-organized structure of the file tree. Otherwise the library users will have big troubles with glitches. It can be even worse, when two libraries are in conflict with one another.