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

时间:2016-03-25 11:39:31

标签: python python-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正在运行,但是只导入file1(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

  

导入模块X,并在中创建对该模块的引用   当前命名空间然后,您需要定义完成的模块路径   从模块内部访问特定属性或方法(例如:   X.nameX.attribute

from X import *

  

导入模块X,并创建对所有公共对象的引用   由当前命名空间中的该模块定义(即一切   没有以_开头的名称或任何名称   你提到过。

     

或者换句话说,在你运行这个陈述之后,你可以简单地说   使用普通(非限定)名称来引用模块X中定义的内容。   但X本身未定义,因此X.name不起作用。如果name   已经定义,它被新版本取代。如果X中的名字是   更改为指向其他对象,您的模块将不会注意到。

     

这使得模块中的所有名称都可以在本地命名空间中使用。

3 个答案:

答案 0 :(得分:3)

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

def x1():
    print "x1"

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

from file2 import y2

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

答案 1 :(得分:0)

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

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

此文件内容应与问题中提到的相同。

答案 2 :(得分:-1)

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

您无法使用x import y,因为每个模块都需要在导入之前完全加载其他模块(对于我们导入的名称存在)。 导致上述错误

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

取代

你可以将另一个文件中的两个文件(或一个)所需的功能或从属文件中分离出来并从中导入

您也可以尝试使用try和例外:

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

关于这个主题的一个好主题:

Circular (or cyclic) imports in Python