简体   繁体   中英

Circular imports Python

I've read this post about circular imports in Python. It describes the following scenario and argues that this raises an error when run:

# module1
import module2

def function1():
    module2.function2()

def function3():
    print('Goodbye, World!')
# module2
import module1

def function2():
    print('Hello, World!')
    module1.function3()
# __init__.py
import module1

module1.function1()

But when I run this (Python 3.95), it runs perfectly fine. The post is pretty old and it doesn't specify the Python version it uses. Maybe there was some change in latter Pythons that support this?

Here's a simplified sequence of events that happen in the code in Python 3:

  1. __init__.py starts running
  2. import module1 starts loading module1.py
    • An empty module1 module is added to sys.modules
  3. import module2 starts loading module2.py
    • An empty module2 module is added to sys.modules
  4. module2.function2 is created and added tomodule2.__dict__
    • The fact that function2 references names in module1 does not affect the creation of the function object in any way
  5. module2 is fully loaded and execution returns to module1
  6. module1.function1 and module1.function3 are created and added to module1.__dict__
    • Again, it does not matter what names the functions reference because they are not being called. AttributeError and NameError can be raised at runtime if necessary.
  7. module1 is fully loaded and execution returns to __main__
  8. module1.function runs successfully, since all the names it references are resolvable.

As you can see, there are no circular import issues in this particular sequence of imports because module1 and module2 do not attempt to call each other's functions. The current import system allows both modules to load before the functions are called.

The post you mention is from 2017, and must be using a version of python from before 3.0. A hint is found in the link in the following quote, which links to the python-2.x docs:

This approach doesn't contradict Python syntax, as the Python documentation says : "It is customary but not required to place all import statements at the beginning of a module (or script, for that matter)".

The paragraph after that is a bit misleading by the way:

The Python documentation also says that it is advisable to use import X , instead of other statements, such as from module import * , or from module import a,b,c .

While star imports are certainly discouraged, specific-name imports of the form from module import a,b,c are generally very much encouraged with few exceptions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM