Modules and packages¶
Python, in addition to importing functions from embedded libraries, allows to use the same mechanisms when attaching code from our modules ...
Modules import¶
For example we have five files in the current directory: modul_a.py
, modul_b.py
, modul_c.py
, modul_d.py
and modul_e.py
. modul_a.py
is the module that stores the definition of the function named find_index
and variable named test
. This is a file inside the project that does not belong to the standard Python library. Other modules may get objects defined in modul_a.py
to prevent code duplication. If any module needed the functionality offered by find_index
, it could either write its own function or use an existing one. The second option is much better: it shortens the amount of code and, in the event of an error, you make changes in only one block of code instead of five, which significantly reduces the working time and prevents the generation of subsequent errors.
This is modul_a.py
:
modul_a.py
test = "Some inscription"
def find_index(to_search, target):
for index, value in enumerate(to_search):
if value == target:
return index
return -1
The find_index
function returns the index of the target element if it appears on the to_search list or -1 if not found.
Similar to importing code from embedded libraries, you can also import author files in four ways.
Method 1¶
After executing the code from the file modul_b.py
, the string 'Some string'
should be printed correctly and the value 0 should be displayed, because the string 'Gym'
is just under such an index in the list courses
.
modul_b.py
# Import module
import modul_a
print(modul_a.test)
courses = ["Gym", "History", "Mathematic"]
index = module_a.find_index(courses, "Gym")
print(index) # Return 0
This time, the entire module modul_a.py
has been imported, not a single function or variable, so use the dot operator to get to the sourced objects .
.
Method 2¶
The module modul_c.py
works exactly like the previous one. It only differs in the way it imports external dependencies.
modul_c.py
# Import whole modul as m_a
import modul_a as m_a
print(m_a.test)
courses = ["Gym", "History", "Mathematic"]
index = m_a.find_index(courses, "Gym")
print(index) # Return 0
If the module name is considered to be too long to be preceded by a call to each function, you can shorten that name in the middle of the module modul_c.py
, calling it using the command import modul_a as m_a
. From now on in the modul_c.py
file, all components of the imported module should be referred to by name m_a
, because it became a local alias (nickname) of the name modul_c
. The previous name can no longer be used.
Method 3¶
How file modul_d.py
handle code insource:
modul_d.py
# Import only find_index function
from modul_a import test, find_index
courses = ["Gym", "History", "Mathematic"]
index = find_index(courses, "Gym")
print(index) # Return 0
There is no need to import the entire file, only its selected components. If instead of the entire module modul_a
we import only the functionfind_index
we lose access to the variable test
, also declared in this module. Thanks to this, we will not have to precede the function name find_index
with the module name and use the dot operator. If it is also necessary to use the variable test
, it can be attached to the module by comma.
Method 4¶
Importing all attributes of a given module is possible thanks to the asterisk operator. It should be remembered that this is not a recommended practice and may cause problems if a name collision occurs in our file or other module that we import in a similar way.
modul_e.py
# Import all variables and functions
from modul_a import *
print(test)
courses = ["Gym", "History", "Mathematic"]
index = find_index(courses, "Gym")
print(index) # Return 0
How Python looks for modules?¶
All previous examples were based on the scenario where all of modules are in the same directory. What would happen if the files were in other folders? Python looks for modules in the locations specified by the path
list from the sys
built-in library. The list of paths that will be searched to find imported modules can be obtained from this variable.
Here is the order of places Python looks in for a file which content we decided to include in the module:
- Current directory.
- Elements derived from the system variable
PYTHONPATH
. - Location of standard Python libraries.
- Location of additional external Python libraries (not included in the installer).
Python always (if there is no interference from the programmer), in the first place, it will search the catalog of the module that performs the import operation inside.
If the module being the object of the operation is not found in the searched directory, Python will ask the system for access to the system variable named PYTHONPATH
, in which the user can place paths to places that would be searched by the interpreter.
In case of previous failure, Python will check if the given module is a built-in library, and if it fails, it will search the directory with packages installed from the outside.
When the locations in the sys.path
list will not return any result and the module is not found, anModuleNotFoundError
exception will be returned.
sys.path list update¶
Since the sys.path
list is a list of locations to be searched, a new entry can be added to it dynamically while the program is running. This is not the best solution - you would then need to add a new location at the top of each (!) file that would use the imported module.
We can add a new location to the system variable PYTHONPATH
. PYTHONPATH
is a variable that tells Python where to look for additional modules. The way you set system variables depends on an operating systems - this is done differently under Linux than under Windows. In Windows, this can easily be done through the user interface or using the set
command on the command line. Linux programmers will need to use the export
program.
Easy way to display sys.path
list:
import sys
print(sys.path)
Attribute __file__¶
Just because we don't need to know the location of files from the standard library does not mean that we cannot know them. Python does not hide their location in any way.
Each module has a special attribute __file__
, whose value is the path to its location on the disk. So we can write the value of this attribute in the console and open the file from the path indicated in the editor to see what is hidden in it. The standard library modules are of course commonly Python files, so you can read them without any problems and you can learn a lot from them.
Packages¶
Just as a file with a special extension (.py
) corresponds to a module in Python, so does the directory where such files are located correspond to a package (package). The Python package is therefore a directory containing files with the extension .py
.
For Python to take a directory as a package, it must contain a special file called __init__.py
. File __init__.py
may be empty or contain generic code for the package. Its most important function is to be a marker for Python so that it interprets the directory as a package.
The following screenshot of the command line shows the package school
along with four files contained in it:
How to import entire packages?¶
Like modules, packages are also have some import rules. Since directories do not contain code, they only store listing files, they serve more as a namespace for modules. In large projects it is easy to imagine the existence of two modules with the same name. By placing them in different packages, the third file can import them both and successfully use their code.
Some information on importing packages:
- If the module is in a location known to Python, you can import it.
- You can import a single module from a package.
- Nothing prevents you from using the operator
*
and import all modules from the package.
# Path to school package needs to
# be added to variable PYTHONPATH
import school
from school import student
from school import student, teacher
from school import *
from school import classroom as room
Import Convention¶
There are a number of recommendations that you should use to write python code. Many standards have been created, including internal ones, created especially for the needs of one team. The main and official standard is PEP (eng. Python Enhancement Proposals). Here's what you can find about imports:
- One 'import' in the line - do not import modules after the comma!
- It is forbidden to import classes, variables, etc. - only whole modules.
- Imports divided into three sections:
- modules from the standard library,
- module from external libraries,
- modules inside the project (our code).
- Within one section, imports should be listed alphabetically.