The concepts of packages, modules, classes in Django
2024
Let’s break down the concepts of packages, modules, classes, and how Python’s __init__.py
integrates them all. We’ll cover:
- Folder Structure (Packages and Modules)
- Classes
- How
__init__.py
works - Example to differentiate between folder location and class usage
1. Folder Structure (Packages and Modules)
- Package: A folder containing Python files, usually including an
__init__.py
file. The folder acts as a package when imported. - Module: A single Python file that can contain functions, classes, and variables. A module is typically a
.py
file inside a package or by itself.
In Django, when you import django.db.models
, you are referring to:
django
: A package (folder).db
: A subpackage insidedjango
.models
: A module (file) inside thedb
package.
Example Folder Structure:
Let’s simulate a simple structure similar to Django’s django.db.models
.
myproject/
mypackage/
__init__.py
db/
__init__.py
models.py
utils/
__init__.py
helper.py
mypackage/
is a package because it has an__init__.py
file.db/
is a subpackage because it’s a folder insidemypackage
and has its own__init__.py
file.models.py
is a module inside thedb
subpackage.utils/
is another subpackage with its own files.
2. Classes
You can define classes inside modules. For example, inside models.py
, you might define a class:
# myproject/mypackage/db/models.py
class Model:
def __init__(self, name):
self.name = name
def __str__(self):
return f"Model name: {self.name}"
his is similar to Django’s models.Model
. Now, you can import and use this class.
3. How __init__.py
Works
The __init__.py
file is a special file that Python treats as the initializer for packages. Without it, Python won’t recognize the folder as a package. It also allows you to control what gets imported when you use the import
statement.
You can use __init__.py
to:
- Expose certain modules or classes from the package.
- Initialize some logic when the package is imported.
Example of an __init__.py
:
# myproject/mypackage/db/__init__.py
from .models import Model # Exposes the Model class from models.py when db is imported
Now, when you import mypackage.db
, you can directly use Model
because it’s exposed in __init__.py
.
4. Example to Differentiate Folder Structure and Class Usage
Here’s how you can see the distinction between folder location and class usage.
- Folder Location:
- You set up folders as packages and subpackages, like
mypackage/db/models.py
.
- You set up folders as packages and subpackages, like
- Class Usage:
- The class is defined in a specific module (
models.py
), and you access it via imports.
- The class is defined in a specific module (
Putting It All Together:
File: myproject/mypackage/db/models.py
class Model:
def __init__(self, name):
self.name = name
def __str__(self):
return f"Model name: {self.name}"
File: myproject/mypackage/db/__init__.py
File: myproject/test.py
from mypackage.db import Model # Imports Model via __init__.py in db
model_instance = Model("Test Model")
print(model_instance) # Output: Model name: Test Model
Key Takeaways:
- Package: A folder with an
__init__.py
file (can contain modules and subpackages). - Module: A Python file (
.py
) that contains code, like classes and functions. - Class: A blueprint for creating objects, defined inside a module.
__init__.py
: Initializes a package and allows you to expose specific modules or logic when the package is imported.
In Your Example (django.db.models
):
django
is the root package (folder).db
is a subpackage (folder insidedjango
).models
is a module (file insidedb
).Model
is a class insidemodels.py
.
Building a own module in Python
Building a module in Python is straightforward. A module is simply a Python file (.py
) that contains definitions, such as functions, classes, and variables. Let’s walk through the process of creating a module and using it in another Python script.
Steps to Build a Module
- Create a Python File (Module)
- Define Functions, Classes, or Variables in the Module
- Import the Module and Use its Content
1. Create a Python File (Module)
Start by creating a simple Python file. Let’s assume you create a file called mymodule.py
inside a folder called myproject
.
File: myproject/mymodule.py
# This is a simple module called 'mymodule.py'
def greet(name):
return f"Hello, {name}!"
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def introduce(self):
return f"My name is {self.name} and I am {self.age} years old."
# A simple variable
version = "1.0"
In this module, we have:
- A function
greet
that takes a name and returns a greeting. - A class
Person
with a methodintroduce
. - A variable
version
.
2. Import the Module and Use It
Now, create another Python file in the same directory (myproject
) where we’ll import the mymodule
and use its contents.
File: myproject/main.py
# Import the custom module 'mymodule'
import mymodule
# Using the greet function from the module
greeting_message = mymodule.greet("Azeem")
print(greeting_message) # Output: Hello, Azeem!
# Using the Person class from the module
person_instance = mymodule.Person(name="Azeem", age=30)
print(person_instance.introduce()) # Output: My name is Azeem and I am 30 years old.
# Accessing the version variable
print(f"Module Version: {mymodule.version}") # Output: Module Version: 1.0
Running the Module
To see the results, you would run main.py
:
$ python myproject/main.py
3. Using from
Import to Directly Access Components
Instead of importing the entire module, you can import specific parts of it using the from
syntax:
File: myproject/main.py
(alternative way to import)
# Import only the greet function and Person class from mymodule
from mymodule import greet, Person
# Using greet function directly
greeting_message = greet("Azeem")
print(greeting_message) # Output: Hello, Azeem!
# Using Person class directly
person_instance = Person(name="Azeem", age=30)
print(person_instance.introduce()) # Output: My name is Azeem and I am 30 years old.
Key Takeaways:
- A module is a Python file that contains code (functions, classes, variables) that you can import and use in other files.
- You can import the whole module using
import mymodule
, or specific parts of it usingfrom mymodule import ...
. - If you place modules inside folders and want them to behave as packages, ensure the folder has an
__init__.py
file (for older Python versions; not required for Python 3.3+).
In Python, the __init__.py
file has an important role in defining a package. However, with newer versions of Python (3.3+), the __init__.py
file is not strictly required for a folder to be treated as a package. This is why you didn’t see it being used explicitly in the example I gave.