2

我注意到 python 如何处理模块名称的一种特殊行为。

如果我写:

import a.b
import a

然后尝试引用模块 ab 中的某些内容,它可以正常工作。

但是,如果我尝试一些稍微不同的东西:

import a.b
import c as a

然后尝试在模块 ab 中引用某些东西,我得到一个错误,说:

AttributeError:“模块”对象没有属性“b”

我知道显而易见的解决方案就是不使用两个我用相同名称引用的不同模块。但是,我仍然很好奇是什么导致了这种行为变化。为什么一个有效而另一个无效?

4

4 回答 4

11

你为什么期望它起作用?您的所有 4 个 import 语句都是对变量的赋值a。因此,如果您分配ca,它会用没有.b属性的东西覆盖内容。


这是第一种情况下发生的情况:

  1. 运行时import a.b,Python 会加载模块a,然后将模块a.b加载到加载a模块的属性b中。然后它将结果分配给变量a
  2. import a不会导入任何新内容,因为模块已经a加载。它只是将相同的模块从 重新分配sys.modules['a']a

以下是第二种情况发生的情况:

  1. 运行时import a.b,Python 会加载模块a,然后将模块a.b加载到加载a模块的属性b中。然后它将结果分配给变量a
  2. 运行时import c as a,它加载模块c,然后将该模块分配给变量a覆盖内容(a = sys.modules['c'])。sys.modules['a']您可以通过将 的内容与 的内容进行比较来验证这一点a- 在这种情况下它们会有所不同。
于 2012-10-06T17:38:30.573 回答
3

如果你import c as a

它会覆盖你以前的a

所以如果你试着打电话a.b你真的打电话c.b

于 2012-10-06T17:38:22.367 回答
3

在第一种情况下,a指的是实际的包a(包含模块b)。这意味着 thata.b指的是由a.

在第二种情况下,a指的是 module c.py。好像你试过了import c; a = c。现在,如果c没有属性b,它将失败。

于 2012-10-06T17:39:24.403 回答
2

当您执行“import as”语句时,您实际上是在执行任务。所以如果你这样做

import matplotlib as mp

您正在为matplotlibto分配命名空间mp

这包含了分配的所有通常含义。

于 2012-10-06T22:38:08.077 回答