"import pkg.a as a" 和 "from pkg import a" 有什么区别? 这是一个关于it技术的问题。

3
我有两个模块在一个包下形成了循环引用。
/test
  __init__.py
  a.py
  b.py

a.py

import test.b
def a():
  print("a")

b.py

import test.a
def b():
  print("b")

但是当我从Python交互解释器中执行 "import test.a" 时,它会抛出AttributeError: module 'test' has no attribute 'a'。

>>> import test.a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "test/a.py", line 2, in <module>
    import test.b as b
  File "test/b.py", line 1, in <module>
    import test.a as a
AttributeError: module 'test' has no attribute 'a'

但是,当我将其更改为from test import afrom test import b时,它可以正常工作。

那么区别在哪里呢?

我正在使用Python3.5


编辑1:

如@Davis Herring所要求的那样,Python2的行为不同。 使用import test.a as a格式时不会抛出错误。

Python 2.7.12 (default, Dec  4 2017, 14:50:18)
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import test.a

然而,当使用from test import a时,它会抛出错误。
Python 2.7.12 (default, Dec  4 2017, 14:50:18)
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import test.a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "test/a.py", line 2, in <module>
    from test import b
  File "test/b.py", line 1, in <module>
    from test import a
ImportError: cannot import name a

可能是['import module' or 'from module import']的重复问题。 - ndrwnaguib
1
您可能需要将代码和结果对齐。 - Ignacio Vazquez-Abrams
你能否也用Python 2进行测试?我认为那里的行为与现在不同,我们可以用一个好的答案来解决两个问题。 - Davis Herring
1个回答

1

import有三个作用:

  1. 查找并加载尚未在sys.modules中的模块(通常来自磁盘)。
  2. 每个新加载的模块执行完成后,将其分配为其包含包(如果有)的属性。
  3. import的范围内分配一个变量,以允许访问指定的模块。

有许多技巧:

  1. import a.b分配一个变量a,这样您就可以像导入一样写a.b
  2. import a.b as cc分配为模块a.b,而不是之前的a
  3. from a import b可以选择模块或任何其他属性 of a
  4. 循环导入的第1步立即“成功”,因为当导入开始时,sys.modules中的相关条目会被创建。

第2点和第4点解释了使用循环import a.b as b失败的原因:循环导入直接进入第3步,但是导入尝试从尚未发生的外部导入的第2步加载属性。

from模糊性曾经也会导致同样的问题,但在3.5中添加了一种特殊回退以查找sys.modules来支持此情况。相同的方法可能适用于import a.b as b,但目前还没有发生。


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