Home > Backend Development > Python Tutorial > How Can Circular Imports in Python Be Avoided and Resolved?

How Can Circular Imports in Python Be Avoided and Resolved?

Barbara Streisand
Release: 2024-12-27 21:05:10
Original
565 people have browsed it

How Can Circular Imports in Python Be Avoided and Resolved?

Circular Imports in Python: Pitfalls and Solutions

In the realm of Python programming, circular dependencies can arise when modules attempt to import each other. Understanding the behavior of such imports is crucial to avoid potential pitfalls.

When two modules, say foo and bar, mutually import each other using import foo and import bar, the imports will succeed seamlessly as both modules are fully loaded and can reference each other.

However, issues arise when using from imports, such as from foo import abc and from bar import xyz. In these scenarios, each module requires the other to be imported before it can proceed. This cyclical dependency leads to an import error.

To illustrate, consider the following code:

# foo.py
from bar import xyz

def abc():
    print(xyz.__name__)

# bar.py
from foo import abc

def xyz():
    print(abc.__name__)
Copy after login

This code will trigger an ImportError because foo requires bar to be imported before it can execute the from import statement, but bar also requires foo to be imported first.

To handle circular imports effectively, several solutions exist:

  • Top of module; no from; Python 2 only:

    # foo.py
    import bar
    
    def abc():
      print(bar.xyz.__name__)
    
    # bar.py
    import foo
    
    def xyz():
      print(foo.abc.__name__)
    Copy after login
  • Top of module; from ok; relative ok; Python 3 only:

    # foo.py
    from . import bar
    
    def abc():
      print(bar.xyz.__name__)
    
    # bar.py
    from . import foo
    
    def xyz():
      print(abc.__name__)
    Copy after login
  • Top of module; no from; no relative:

    # foo.py
    import lib.bar
    
    def abc():
      print(lib.bar.xyz.__name__)
    
    # bar.py
    import lib.foo
    
    def xyz():
      print(lib.foo.abc.__name__)
    Copy after login
  • Bottom of module; import attribute, not module; from okay:

    # foo.py
    def abc():
      print(xyz.__name__)
    
    from .bar import xyz
    
    # bar.py
    def xyz():
      print(abc.__name__)
    
    from .foo import abc
    Copy after login
  • Top of function; from okay:

    # foo.py
    def abc():
      from . import bar
      print(bar.xyz.__name__)
    
    # bar.py
    def xyz():
      from . import foo
      print(foo.abc.__name__)
    Copy after login

Star imports, however, are not discussed in the examples provided in the original article.

The above is the detailed content of How Can Circular Imports in Python Be Avoided and Resolved?. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template