Delete Set public Set private Add tags Delete tags
  Add tag   Cancel
  Delete tag   Cancel
  • • DevOps notes •
  •  
  • AI
  • Tags
  • Login

Python package and subpackage/shaare/9j4UUQ

  • python
  • python

Introduction to Packages (__init__.py)

What is a Package?

A Python package provides a way to structure a project's module namespace by using directories. It enables a hierarchical organization of modules, mirroring the file system's structure.

  • Any directory that contains a file named __init__.py is recognized by the Python interpreter as a package.
  • A package directory can contain not only module files (ending in .py) but also other subdirectories that are themselves packages.

The Role of __init__.py

  • Its primary role is to serve as a marker, signaling to Python that the directory it resides in should be treated as a package. In older versions of Python, a directory without this file would not be recognized as a package. While newer versions have more lenient rules, explicitly including __init__.py is the standard and most compatible method.
  • The second purpose is for package initialization. Any code written inside the __init__.py file is executed once when the package or any of its modules are first imported, which can be useful for setting up package-level resources. For many packages, this file can simply be left empty.

Importing from a Package

  • You can import the entire module using the full path, such as import devops_utils.file_ops. Accessing its contents would then require the full prefix, like devops_utils.file_ops.check_file_extension().
  • Alternatively, you can use the from keyword to import the module more directly, as in from devops_utils import file_ops, which then allows access via file_ops.check_file_extension().
  • For even more direct access, you can import specific functions or variables, for example, from devops_utils.file_ops import check_file_extension. This makes the function available to be called directly as check_file_extension().

Using __init__.py to Control Imports

  • By importing members from the package's modules into the __init__.py file itself, you can make them appear as if they belong to the top-level package namespace.
  • This technique can create a simpler, more user-friendly API for your package, but it can also obscure the underlying module structure.

Importing from Subpackages

Project Structure with Subpackages

To improve organization, we can group related modules into their own dedicated subpackages. A subpackage is a directory inside a parent package that contains its own __init__.py file.

  • A top-level package, like devops_utils, can contain multiple subpackages.
  • For example, we can create a file_utils subpackage for file-related modules and a network_utils subpackage for networking modules.
  • Each of these subdirectories must contain an __init__.py file (which can be empty) to be recognized by Python as a package.

Absolute Imports

An absolute import provides the complete, explicit path to a module starting from a top-level directory that is on Python's search path (sys.path).

  • The syntax follows the project's directory structure, such as from package.subpackage.module import function.
  • This is the most recommended and readable way to import modules, particularly in top-level scripts that execute the application's logic.
  • Absolute imports are unambiguous and clearly state the origin of the imported code, which greatly improves code maintainability. For example, a script outside the devops_utils package would use from devops_utils.file_utils.file_ops import check_file_extension to access a function.

Relative Imports

A relative import specifies the path to a module based on the location of the file performing the import. This is done using dot notation.

  • The syntax uses dots to navigate the package hierarchy: . refers to the current package, while .. refers to the parent package.
  • An import like from .sibling_module import name brings in a name from a module in the same directory. An import like from ..parent_sibling.module import name navigates one level up and then down into a sibling package.
  • Relative imports are primarily used for communication within a package. Their main advantage is that they make the package self-contained; if you rename the top-level package, the internal relative imports will not break.

The ImportError Trap with Relative Imports

A significant pitfall arises when you attempt to directly execute a Python file that contains relative imports. This action will almost always result in an error.

  • Running a script like python devops_utils/network_utils/network_ops.py will raise an ImportError: attempted relative import with no known parent package.
  • This happens because when a file is run directly, Python sets its name (__name__) to "__main__" and does not recognize it as being part of a package. Consequently, it cannot resolve relative paths like . or ...
  • The rule of thumb is that relative imports should only be used for intra-package imports, and the application should be started from a top-level script that uses absolute imports to access the package's functionality.
1 month ago Permalink
cluster icon
  • Classes and Objects : Classes and Objects Beyond Built-ins: Python lets you define your own data types using class. Class: A blueprint or template for creating objects. De...
  • Lambda Functions : Lambda Functions Python functions defined with def allow multiple statements, clear naming, and support for docstrings, making them ideal for complex...
  • Editable Installs with pyproject.toml : Editable Installs with pyproject.toml The Python interpreter doesn't automatically know about our project's structure. The modern and most robust solu...
  • List : Lists (list) Lists are ordered, mutable sequences defined with square brackets []. You can add, remove, or change items after creation. Characteristic...
  • For & While Loops : For & While Loops Python provides two main ways to repeat actions: for loops (for iterating over known sequences) and while loops (for repeating as lo...


(97)
Filter untagged links
Fold Fold all Expand Expand all Are you sure you want to delete this link? Are you sure you want to delete this tag? The personal, minimalist, super-fast, database free, bookmarking service by the Shaarli community