For details about how to avoid circular import in Python

Source: Internet
Author: User

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 errorError, 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.attributeReference functions or variables in another_module. This method is effective becauseimport another_moduleIt 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_moduleThis 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.attributeReference functions or variables in another_module. This is becauseimport .another_moduleIn 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 moduleAttribute, such as frompackage.another_module import attribute, Relative introduction is also supported, suchfrom .another_module import attributeThe 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.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.