Get familiar with Python – Part 2 – Python package & module

Tram Ho

In this part 2, we will learn more about python package and module.

1. Python packages

In the simplest way, if the module is merely a file ending in .py , then the package can be considered a directory containing the modules.

Packages are method for managing python’s module namspace using ” dotted module names “. For example, when we type module name AB , this means we are specifying module B inside package A.

Similar to using modules to help a module writer not to worry about having the same variable / function names in other people’s modules, using dotted module names helps writers to write multi-module packages such as NumPy or Pillow. No need to worry about having the same module name with others.

2. Import statement

Suppose you want to design a collection of modules (a “package”) to process sound files and sound data. These sound files will come in many different formats (commonly identified by their extensions e.g. .wav , .aiff , .au ), so you need to create and maintain a growing collection of modules to convert between different formats.

Next, there are a lot of things you want to do on sound data (e.g. mixing, adding echo, applying equalizer functions, creating sound effects, etc.), so it’s likely that they are. we would have to write an infinitely lengthy series of modules to perform these tasks. Here is a package structure that we can use:

The file is required in order for Python to treat a directory as a package.

In the simplest case, __init.py__ might just be an empty file, but it can be used to run the initialization code, or to set the value for the __all__ variable, as described later.

Package users can import each module separately, for example:

Another way to import submodule:

Or we could go even further, importing the function directly into the symbol table:

Compare from package import item and import item.subitem.subsubitem

With the from package import item , the item can be either a submodule, or a subpackage, or it can be a ✔ function, ✔ class or ✔ variable.

In terms of order, the import statement will check if the name is a definition in that package (function, class, variable), if not, it will implicitly this is a module and try to load the module. .

With import item.subitem.subsubitem , every item except the last, must be a package, the last can be either a module or a package, but it cannot be ❌ function, ❌ class, ❌ variable .

3. Package Relative Imports

Once packages are structured into subpackages (such as a sound package for example), you will be able to use absolute imports to refer to submodules inside siblings packages .

For example, if the sound.filters.vocoder module needs to use the echo module in the sound.effects package, we could write from sound.effects import echo .

Or, we can write releative import , still using the form from module import name . But we will use the leading dots to indicate that the current and parent package are involved in the import process. For example, as we are standing inside the surround module, we can import the following:

Note: with absolute import , we can use either import <> or from <> import <> . But relative import will only use the form from <> import <> . The reason is because, with:

XXX.YYY.ZZZ is a usable expression, but .XXX is not a valid expression.

4. __all__ variable

There is a question, what happens when a user writes from sound.effects import * ?

Ideally, inside the package’s file, a list of the names of the modules to be imported is provided using the __all__ variable. For example

Then, the interpreter will only import the modules whose name is provided in this list.

In case the variable __all__ not defined, the statement from sound.effects import * will NOT import all the submodules of the package sound.effects. It just makes sure that the package sound.effects is imported, runs all code inside the file, and imports all the names defined in the package. These names include all the functions, classes, and variables defined inside the file and the submodules that are explicitly loaded.

At this point, we will see that the following two ways are equivalent:

Even though both methods produce the same results, import * still considered bad practice . And from package import specific_submodule is the recommended way.

Share the news now

Source : Viblo