For details about how to avoid circular import in Python
Preface
When using a package in Python, It is very common to have a circular import problem. We create the following package to illustrate this problem:
pkg ├── __init__.py ├── module_a.py └── module_b.py
Where,
_ Init _. py: Specify pkg as a Python package.
Module_a.py definesaction_a()
Function, which references an attribute in module_ B .py, such as a function or variable.
Module_ B .py definesaction_b()
Function, which references an attribute in module_a.py, such as a function or variable.
In this case,circular import error
Error, that is, loop reference. Because module_a tries to introduce module_ B, module_ B first introduces module_a, which causes the Python interpreter to fail to execute.
However, we can use some clever methods to make the above logic work normally and avoid errors introduced cyclically.
So, when can it work normally, and when cannot it work normally? What are the reasons for working properly?
When does it work normally?
1. Import at the top of the module. Do not use from. It is effective only in Python 2.
Import at the top of the module, as shown in figureimport another_module
, The function in module usesanother_module.attribute
Reference functions or variables in another_module. This method is effective becauseimport another_module
It is based on the relative reference of the current directory and is an implicit reference. If the module is introduced from another package, it will become invalid. In addition,import another_module
This syntax is not supported in Python3, so do not use this method in code to avoid loop introduction.
For example:
# pkg/module_a.py from __future__ import print_functionimport module_b def action_a(): print(module_b.action_b.__name__) # pkg/module_b.pyfrom __future__ import print_functionimport module_a def action_b(): print(module_a.action_a.__name__)
2. introduce it at the top of the module. Do not use from. Absolutely introduce it.
Import at the top of the module and use the absolute path starting from package, as shown in figureimport package.another_module
, The function in module usespackage.another_module.attribute
Reference functions or variables in another_module. This is becauseimport .another_module
In this form of "relative Introduction", a syntax error is reported, and the absolute introduction of package is supported by both Python 2 and Python 3.
Case:
# pkg/module_a.pyfrom __future__ import print_functionimport pkg2.module_b def action_a(): print(pkg2.module_b.action_b.__name__) # pkg/module_b.pyfrom __future__ import print_functionimport pkg2.module_a def action_b(): print(pkg2.module_a.action_a.__name__)
3. Introduce the attribute of the another module at the bottom of the module, instead of the another module.
Import at the bottom of the module (at least after the referenced attribute), directly introduceanother module
Attribute, such as frompackage.another_module import attribute
, Relative introduction is also supported, suchfrom .another_module import attribute
The function in module can directly use the referenced attribute.
For example:
# pkg/module_a.pyfrom __future__ import print_function def action_a(): print(action_b.__name__) from .module_b import action_b # pkg/module_b.pyfrom __future__ import print_function def action_b(): print(action_a.__name__) from .module_a import action_a
4. introduced at the top of the function. You can use from
Import the function at the top of the module, as shown in figurefrom package import another_module
. You can also introduce modules or attributes.
For example:
# pkg/module_a.pyfrom __future__ import print_function def action_a(): from . import module_b print(module_b.action_b.__name__) # pkg/module_b.pyfrom __future__ import print_function def action_b(): from . import module_a print(module_a.action_a.__name__)
Or
# pkg/module_a.pyfrom __future__ import print_function def action_a(): from .module_b import action_b print(action_b.__name__) # pkg/module_b.pyfrom __future__ import print_functiondef action_b(): from .module_a import action_a print(action_a.__name__)
This method is supported by Python 2 and 3, but the encoding is not elegant enough to affect code readability.
Note
This article discusses how to avoid loop introduction when calling a package in Python.
When you directly execute a Python module on the command line, the application is not exactly the same
Summary
The above is all the content of this article. I hope the content of this article has some reference and learning value for everyone's learning or work. If you have any questions, please leave a message to us, thank you for your support.