“import pkg.a as a”和“from pkg import a”有什么区别?

时间:2018-04-11 21:37:49

标签: python python-3.x

我有两个模块在包

下形成循环导入
/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:模块'test'没有属性'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

1 个答案:

答案 0 :(得分:1)

import做了三件事:

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

    1. import a.b分配变量a,以便您可以像导入一样编写a.b
    2. import a.b as cc指定为模块a.b,而不是a
    3. from a import b可以选择a的模块或任何其他属性
    4. 循环导入的步骤#1立即“成功”,因为导入开始时创建sys.modules中的相关条目
    5. 点#2和#4用循环import a.b as b解释失败:循环导入直接进入步骤#3,但导入尝试从外部的步骤#2加载属性尚未发生的导入。

      from含糊不清used to cause同样的问题,但在sys.modulesspecial fallback添加了{{3}}以支持此案例。同样的方法可能适用于import a.b as b,但这还没有发生。