递归导入:'import'与'from ... import...'的区别

7

我有两个文件,它们需要互相使用不同的函数。

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
我已经阅读了关于导入的thisimport X 引入模块X,并在当前命名空间中创建对该模块的引用。然后您需要定义已完成的模块路径才能从模块内部访问特定属性或方法(例如:X.nameX.attribute)。 from X import * 导入模块X,并在当前命名空间中创建对该模块中所有公共对象的引用(即,所有名称不以_开头的对象),或者您提到的任何名称。换句话说,在运行此语句之后,您可以使用简单(未限定)名称来引用在模块X中定义的内容。但是,X本身没有被定义,因此X.name无法工作。如果name已经定义,则会被新版本替换。如果在X中更改了名称以指向其他对象,则您的模块将不会注意到。这使得模块中的所有名称都在本地命名空间中可用。

不要使用循环导入。如果函数之间关联紧密,它们应该放在同一个模块中。 - Daniel
2
@Daniel 循环导入可能很少见,但它们有其用途。仅因为两个模块彼此依赖并不意味着它们属于同一模块。例如,子模块有时需要导入其父模块。 - Konrad Rudolph
2个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
4

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

def x1():
    print "x1"

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

from file2 import y2

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


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

这个文件的内容应该与问题中提到的相同。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,