SoFunction
Updated on 2024-11-07

Python Modularization - Modules and Packages

introductory

When you're new to python, terms like modular programming, modules, libraries, etc. are often not easy to sort out. Modules and packages, in particular, are easy to confuse when importing references.

In fact, Python function (Function), class (Class), module (Module), package library (Package), are designed to achieve modular references, so that the organization of the program is more clear and structured.

  • Typically, functions, variables, and classes are stored in .py files called modules, which in turn form packages.
  • Storing functions, variables, and classes in stored in separate .py files hides the details of the code implementation, reorganizes the different code blocks, separates them from the main program, simplifies the logic of the main program, and improves the readability of the main program.
  • With package and module files, it is possible to reuse them in other different programs and also to use third-party dependency libraries developed by others.

Python Modules

Modules2 modules are files that contain Python definitions and statements. A filename with a .py extension is the module name.

Within a module, the name of the module can be represented (as a string) by the global variable __name__.

As an example, we created a file with the contents of:

# Fibonacci numbers module
def fib(n):    # write Fibonacci series up to n
    a, b = 0, 1
    while a < n:
        print(a, end=' ')
        a, b = b, a+b
    print()
def fib2(n):   # return Fibonacci series up to n
    result = []
    a, b = 0, 1
    while a < n:
        (a)
        a, b = b, a+b
    return result

Here is a module, fib, fib2 are functions in the fibo module.

import module

If we want to use the fibo module in another program, there are three ways to import it:

①Import the whole module

#import module_name
import fibo

Any of these functions can be used using the following syntax:

#module_name.func()
(10)

⭕ Note: Module name + sentence point cannot be omitted here.

② Importing specific functions in a module

#from module_name import function_name
from fibo import fib, fib2
fib(10)

If you use this syntax, you don't need to use the module name + period when calling the function.

Because the functions fib and fib2 have been explicitly imported in the import statement, you only need to specify their names when calling it.

③Import all functions in the module

#from module_name import *
from fibo import *
fib(20)

This approach imports all functions except those whose names begin with an underscoreable (__).

⭕ Note: In most cases, *this* usage is usually not recommended, as it may introduce an unknown set of names into the interpreter and usually results in less readable code.

Give the imported module an alias

# import module as m
import numpy as np
a = (100)

Use as to give an alias to the imported module to simplify writing calls in the code.

stand-alone module

If we want to test the module separately, we can add the following code to the module, and it can be used both as a script and as an importable module:

if __name__ == "__main__":
    import sys
    fib(int([1]))

Run the modules individually:

python  100

This code, which parses the command line, is only run when the module is executed as the "main" file.

Accelerated module loading

To speed up module loading, Python caches the compiled version of each module (e.g., *.pyc) in a directory under __pycache__. For details on generating the compiled file pyc, see document PEP 3147.

Python checks the modification date of the source code against the compiled version to see if it is out of date and needs to be recompiled.

Python Packages

Packages packages can be understood as containers for a set of modules and are used in a way to build namespaces3.

By analogy with a file system, you can think of packages as directories on a file system and modules as files in a directory.4

For example, a submodule named A in a package named B is specified.

Using such an approach, you can avoid the problem of conflicting naming between packages of some multi-modules, somewhat similar to namespace references such as std::string, cv::imread, etc. in C++.

For example, this is an example of an official package that provides sound packages on sound processing:

sound/                          Top-level package
      __init__.py               Initialize the sound package
      formats/                  Subpackage for file format conversions
              __init__.py
              
              
              ...
      effects/                  Subpackage for sound effects
              __init__.py
              
              ...
      filters/                  Subpackage for filters
              __init__.py
              
              ...
  • __init__.py must be present in order for Python to treat the directory containing the file as a Package. __init__.py can be an empty file, or it can execute the package's initialization code or set the __all__ variable.
  • formats/, effects/, and filters/ are subpackages, each of which also has an __init__.py file.
  • etc. files are modules in subpackages, which may contain functions, classes, or variables.

Referencing Modules in Packages

from  import echo
(input, output, delay=0.7, atten=4)

This way, the function can be referenced directly without the prefix of the front bread.

Reference to a function or variable in a submodule of a package.

from  import echofilter
echofilter(input, output, delay=0.7, atten=4)

This approach loads the submodule echo while making the echofilter() function directly available in the submodule.

The from package import item statement tests to see if the item is defined in the package; if it is not, it assumes the item is a module and tries to load it. If it still can't find the item, it triggers the usualImportError exception.

Referencing packages and modules with relative paths

from . import echo
from .. import formats
from ..filters import equalizer

The . You can access packages or modules in the same directory.
Here. gives access to packages or modules in the previous directory.

Use __all__ to provide explicit indexing of packages

When we use from import * directly, it may reference something that is not needed or cause slow loading.

At this point we can specify the list of module names that should be imported with * by defining an _all__ list in __init__.py:

__all__ = ["echo", "surround", "reverse"]

This allows us to maintain a list of modules that need to be imported when importing * which is useful when releasing different versions of a package.

Package your own Package and distribute it

To package your own Package via the setuptool tool, you can refer to these two documents:

/tutorials/packaging-projects/
How to add the necessary files and structures to create packages, how to build packages, and how to upload them to the Python Package Index.

/guides/distributing-packages-using-setuptools/
Introduces the basics of how to configure, package, and distribute your own Python projects.

Installing Packages from the python community

Note that a Package, in the python community, usually refers to the package of a distribution, not a container of modules in the source code.

Common packages can be found by checking out PyPI:/ and installing the community-provided Packages by using pip install.

summarize

Modularity is the organization of related code into files at different levels to facilitate reuse and improve code readability.

Functions, variables, and classes are stored in .py files called modules, which in turn form packages.

To introduce Package packages or Module modules, you can use import ... or from ... import ..., and you can also refer to higher-level packages and modules via relative paths.

That's all for this post, I hope it helped you and I hope you'll check back for more from me!