关于python:”import pkg.a as a”和”from pkg import a”有什么区别?

What is the difference between “import pkg.a as a” and “from pkg import a”?

我有两个模块组成一个包下的循环导入

1
2
3
4
/test
  __init__.py
  a.py
  b.py

A.Py

1
2
3
import test.b
def a():
  print("a")

B.Py

1
2
3
import test.a
def b():
  print("b")

但是当我从python交互式解释器中执行"import test.a"时,它会抛出attributeError:module"test"没有属性"a"。

1
2
3
4
5
6
7
8
>>> 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格式时,不会引发错误。

1
2
3
4
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时,它会抛出错误

1
2
3
4
5
6
7
8
9
10
11
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做了3件事:

  • 查找和加载不在sys.modules中的模块(通常从磁盘)。
  • 在每个新加载的模块完成执行之后,将其作为包含它的包(如果有)上的属性分配。
  • import的范围内分配一个变量,以允许访问指定的模块。
  • 有很多技巧:

  • import a.b指定一个变量a,这样您就可以像在导入中一样写入a.b
  • import a.b as cc指定为modulea.b,而不是以前的a
  • from a import b可以选择a的一个模块或任何其他属性。
  • 循环导入的步骤1立即"成功",因为在导入开始时创建EDOCX1[1]中的相关条目。
  • 点2和点4解释了循环import a.b as b的失败:循环导入直接进入步骤3,但导入尝试从尚未发生的外部导入的步骤2加载属性。

    from模糊性曾导致同样的问题,但在3.5中添加了一个特殊的回退来支持这个案例。同样的方法可能也适用于import a.b as b,但这还没有发生。