When executing from the entry point of the application itself, even if there is no problem in execution When I started each module file as an entry point, I sometimes stumbled on the import statement, so I investigated the solution.
--6/12: Fixed because except in try ~ except statement was catch.
As a sample, consider the following directory / file structure.
main.py ...Executable file as an application
|
|--[src] ...Directory for storing modules
|
|-- module1.py ... main.Module called from py
|-- module2.py ... module1.Module called from py
If the entry point as an application is main.py, only the directory containing main.py will be recognized as the python path. Therefore, all the files that make up this application need to be imported starting from the directory where main.py is located. In other words, if you want to use module1.py through module2.py in the above directory structure,
/src/module1.py
# -*- coding: utf-8 -*-
import module2 # ImportError!
Then no
/src/module1.py
# -*- coding: utf-8 -*-
import src.module2 # OK
Must be.
This description is fine for operation, but problems occur when writing test code in module1.py.
The test code here is supposed to check the operation of classes and functions in module1.py. Isn't it a fairly common sight to write a simple code that calls a function in the file and press the F5 key to see the behavior of the code you wrote on the spot?
However, if you write ʻimport src.module2, when you start the program with module1.py as the entry point, the
srcpart cannot be recognized and an ImportError will occur. This is because the execution directory when starting from module1.py changes to the src directory. There is no directory called
src` in the src directory.
In this article, I will introduce three ideas that solve this problem and allow you to start the program from either main.py or module1.py. By the way, all have disadvantages and it is not OK if you do this. We are looking for a smarter way, so please comment.
--How to sys.path.append () in the module file -How to sys.path.append () with \ _ \ _ init \ _ \ _.py --How to catch ImportError and branch
This is a solution by writing sys.path.append ()
in module1.py.
I think it's a fairly common method.
/src/module1.py
# -*- coding: utf-8 -*-
import sys, os
sys.path.append(os.path.join(os.path.dirname(__file__), '.'))
import module2
This is to add the directory containing the module1.py file to the python path.
By doing this, the src directory will be added to the python path and the error will not occur even if the import statement does not have src
.
In other words, you only need to import module2.py with ʻimport module2`.
However, this method has the problem that if there are a large number of module files, the above description for each file becomes necessary.
Also, sys.path.append ()
is reflected in all files using module1.py, which pollutes the namespace.
(You will be able to create ʻimport module 2` in main.py.)
It is a method to place \ _ \ _ init \ _ \ _. Py directly under the src directory and perform sys.path.append ()
in it.
In this case, the directory structure looks like this:
main.py ...Executable file as an application
|
|--[src] ...Directory for storing modules
|
|-- __init__.py ... sys.path.append()File to run
|-- module1.py ... main.Module called from py
|-- module2.py ... module1.Module called from py
Also, the contents of \ _ \ _ init \ _ \ _. Py are as follows.
/src/__init__.py
# -*- coding: utf-8 -*-
import sys, os
sys.path.append(os.path.join(os.path.dirname(__file__), '.'))
What this is doing is that when you do ʻimport src.module1 in main.py, \ _ \ _ init \ _ \ _. Py is also implicitly imported. Specifically, when executing ʻimport src.module1
from main.py, \ _ \ _ init \ _ \ _. Py is imported first, and then module1.py is imported. I will.
for that reason,
sys.path.append ()
is executed and the src directory is added to the python path.It will be the operation.
This way you can reduce the amount of code because each module in the src directory does not need sys.path.append ()
.
However, as long as you use sys.path.append ()
, the namespace pollution issue remains.
It is a method to catch ImportError and change the import destination dynamically without using sys.path.append ()
.
Specifically, the code is as follows.
/src/module1.py
# -*- coding: utf-8 -*-
try:
import src.module2 # main.If you start from py, this will be executed
except ImportError:
import module2 # module1.If you start from py, this will be executed
If ʻimport src.module2 fails, ʻimport module2
is executed instead.
Normally, the application runs from main.py, so you can see the src directory from the execution directory.
Therefore, when starting from main.py, the contents of the try block will be executed without any problem.
On the other hand, if you start module1.py as an entry point, you will get an ImportError because you cannot see the src directory. Therefore, catch ImportError in the except block and change the description of the import destination so that it can be imported successfully.
This technique does not use sys.path.append ()
, so it does not pollute the namespace.
However, the problem of having to add the above description to each module file remains.
In this article, I've shown you three ways you can start a program from either main.py or module1.py.
--How to sys.path.append () in the module file -How to sys.path.append () with \ _ \ _ init \ _ \ _.py --How to catch ImportError and branch
However, there are disadvantages to each method, so I wonder if it is necessary to use them properly according to the environment.
Recommended Posts