Python Packages
In Python, a package is a way of organizing related modules into a single directory hierarchy. Packages are used to create a namespace, prevent naming conflicts, and structure the code in a more organized manner. A package is a directory that contains a special file named __init__.py
(which can be empty) to indicate that the directory should be treated as a Python package.
Creating a Package
- Create a directory for your package (e.g.,
mypackage
). - Inside the package directory, create a file named
__init__.py
(can be empty). - Create module files within the package directory (e.g.,
module1.py
,module2.py
).
The structure should look like this:
mypackage/
|-- __init__.py
|-- module1.py
|-- module2.py
Module Contents (module1.py)
# module1.py
def func1():
print("Function 1 from module1")
Module Contents (module2.py)
# module2.py
def func2():
print("Function 2 from module2")
Using the Package
Create a script (e.g., main.py
) in the same directory:
# main.py
from mypackage import module1, module2
# Using functions from the modules
module1.func1()
module2.func2()
Importing Submodules
You can also import specific functions or classes from submodules directly:
# main.py
from mypackage.module1 import func1
from mypackage.module2 import func2
# Using functions directly
func1()
func2()
Importing the Whole Package
You can import the entire package and use its modules:
# main.py
import mypackage
# Using functions from modules
mypackage.module1.func1()
mypackage.module2.func2()
Subpackages
You can create subpackages within a package by creating additional directories with __init__.py
files. For example:
mypackage/
|-- __init__.py
|-- module1.py
|-- module2.py
|-- subpackage/
| |-- __init__.py
| |-- submodule1.py
| |-- submodule2.py
Relative Imports
Within a package, you can use relative imports to reference modules or submodules:
# submodule1.py (inside the subpackage)
from ..module1 import func1
Here, ..
refers to the parent package.
Packages in Python provide a powerful way to organize and structure code. They help in avoiding naming conflicts, improve code modularity, and make it easier to manage and distribute code as it grows larger.