递归导入:'import' 与 'from ... import ...'

Recursive import: 'import' vs. 'from ... import ...'

我有两个文件需要使用彼此不同的函数。

file1.py:

import file2   # from file2 import y2

def x1():
    print "x1"

def x2():
    print "x2"
    file2.y2()

file2.py:

import file1   # from file1 import x1

def y1():
    file1.x1()
    print "y"

def y2():
    print "y2"

if __name__ == "__main__":
    y1()

我想知道为什么使用 import file1 有效,但仅从文件 1 (from file1 import x1) 导入特定函数却无效?

Traceback (most recent call last):
  File "file2.py", line 1, in <module>
    from file1 import x1
  File "file1.py", line 1, in <module>
    import file2
  File "file2.py", line 1, in <module>
    from file1 import x1
ImportError: cannot import name x1

我读过this关于导入的内容:

import X

Imports the module X, and creates a reference to that module in the current namespace. Then you need to define completed module path to access a particular attribute or method from inside the module (e.g.: X.name or X.attribute)

from X import *

Imports the module X, and creates references to all public objects defined by that module in the current namespace (that is, everything that doesn’t have a name starting with _) or whatever name you mentioned.

Or, in other words, after you've run this statement, you can simply use a plain (unqualified) name to refer to things defined in module X. But X itself is not defined, so X.name doesn't work. And if name was already defined, it is replaced by the new version. And if name in X is changed to point to some other object, your module won’t notice.

This makes all names from the module available in the local namespace.

循环导入通常表示设计问题,但为了解决它们,您可以在底部编写 import 语句,如下所示:

def x1():
    print "x1"

def x2():
    print "x2"
    file2.y2()

from file2 import y2

请记住,这是一种解决方法。 from x import y 在循环导入的情况下不起作用的原因是当你到达第一个 from ... import ... 时你被传递给第二个模块并且当第二个模块回调第一个时,解释器意识到它是一个永无止境的循环并继续部分导入的模块,这发生在您定义函数之前,这意味着 y2 尚不存在。

就像 bharel 提到的那样,它会导致一个循环,每个函数在完成加载之前不断相互调用,从而导致无限循环并引发此异常

你不能使用 from x import y 因为每个模块都需要在导入之前完全加载另一个模块(我们正在导入的名称存在)。 导致上面的错误

虽然你可以使用 from x import *,但我猜是因为它将被简单的 import x

您可以将两个文件(或一个)中所需的函数分离到另一个文件或从属文件中,并从中导入

您也可以尝试使用尝试和异常:

try:
    from images.serializers import SimplifiedImageSerializer
except ImportError:
    import sys
    SimplifiedImageSerializer = sys.modules[__package__ + '.SimplifiedImageSerializer']

关于这个主题的好话题:

Circular (or cyclic) imports in Python

另一种解决方案是仅在需要时才导入模块。例如,您的情况可以通过以下方法解决:

file1.py

# insted of importing file2 here

def x1():
    print "x1"

def x2():
    print "x2"
    import file2    # import here when you need it
    file2.y2()

file2.py

这个文件内容应该和问题中提到的一样。