In the Python programming language, import
is used to connect packages and modules. This allows the distribution of code into logical “nodes” (data models, handlers, etc.), reducing the burden on code files.
Benefits:
- Increases code readability.
- Divides the code into logical “nodes,” making it easier to find and debug.
- Clarifies each person’s role and responsibility when working as a team.
Drawbacks:
- You need to understand what is being done and why.
How to Use import
in Python
The syntax for import
in Python is simple and straightforward:
# This line imports something_we_want
import something_we_want
# This line imports something_we_want, as aww (Logical and simple)
import something_we_want as aww
# This line imports something from something_we_want (Logical and simple)
from something_we_want import something
# This line imports something from something_we_want, as s (Logical and simple)
from something_we_want import something as s
# The syntax 'as' allows referring to the imported module/function with a new name
# (this only works within our file)
What Can You Import?
To better understand import
, consider the example below.
something_we_want.py:
def something():
pass
somedata = 5
main.py:
# 1st case
import something_we_want
something_we_want.something()
import something_we_want
print(something_we_want.somedata)
# 2nd case
import something_we_want as aww
aww.something()
import something_we_want as aww
print(aww.somedata)
# 3rd case
from something_we_want import something
something()
from something_we_want import somedata
print(somedata)
# 4th case
from something_we_want import something as s
s()
from something_we_want import somedata as sd
print(sd)
# Classes are imported in analogy to functions
Agreed, this is very clean, readable, and easy to understand.
What’s the Catch?
Even in such a simple example, there’s a catch that many people are not aware of. Especially if you are a new programmer, you might proceed assuming otherwise.
Python’s ideology is quite interesting, making it easy to get into, write, and read code. But this is where the catch is hidden.
From my experience using Python, I’ve come to understand that the main idea of OOP is that everything is an object. You might ask, what’s wrong with that?
All files, functions, etc., are objects. But what is the object and class behind files (modules)?
It’s very simple! It’s the most beloved class among programmers using the Singleton design pattern.
Therefore, if your project has a complex structure, importing a variable and modifying it further can be quite difficult to understand. (During its lifecycle, a variable can have any value, and there is no guarantee of its state at any point.)
Detailed Application Structure and Approaches to Importing
In application development, programmers often attempt to divide the application into logical “nodes.” This approach improves code readability and allows for team-based development (one person takes care of implementing a “node,” another of a different one). This is how an application structure is born, which often becomes quite extensive due to the complexity of the functionality. It is referred to as “branched” because there is an entry point from where functionality grows like a tree.
An Example of a Branched Structure:
main.py
app/
models/
User.py
handlers/
auth.py
There are two main approaches for this (it’s best to stick to one approach throughout the project):
- Absolute (named)
- Relative (unnamed)
An Example of Named Import from models.py to auth.py:
# auth.py
from app.models import User
An Example of Unnamed Import from models.py to auth.py:
# auth.py
from ..models import User
# The number of dots indicates how many directories we move up from the original one.
# In this example, the first dot raises us to the level of the handlers directory,
# and the second dot raises us to the level of the app directory.
These are two completely different approaches. In the first case, we “go out” from the “root” (the entry point of our application). In the second case, we go “in” from the “leaf” (our current file).
Pros and Cons of Import Approaches
Approach | Pros | Cons |
---|---|---|
Named | – Visible imports and application structure. – High readability. | – Dependent on the entry point. – Requires knowing the application structure. – Code is very tied to the application, making debugging, testing, etc., more complex. – Programmer becomes overly involved in the project. |
Unnamed | – Part of the import structure is visible. – Does not require knowing the entire application structure. – Import is not dependent on the entry point. – Code is not tied to the application, allowing for execution from anywhere (testing, separately, etc.). – Debugging capability increases. – Enables the possibility for programmers to develop different nodes of the application without being fully involved in the project. | – Import readability decreases. |
Although the first approach has significant drawbacks, it remains popular. Programmers are more accustomed to it, even though it has deficiencies. Beginners often do not think about alternatives.
P.S.
This article was written for novice programmers who want to learn the Python programming language, so some examples are deliberately simple and focused on explaining the existing approaches.
Write the code you want to receive from the executor.