无法识别“导入为”,正常导入是

use*_*941 5 import matplotlib python-3.x

我正在使用 matplotlib 来更好地理解它的结构,但我对以下代码感到困惑:

import matplotlib as mpl
from mpl import pyplot as plt # ModuleNotFoundError : No module named 'mpl'
mpl.pyplot # AttributeError: module 'matplotlib' has no attribute 'pyplot'
Run Code Online (Sandbox Code Playgroud)

另一方面,如果我放弃导入as不同名称的 matplotlib 并执行

import matplotlib
from matplotlib import pyplot as plt #works!
Run Code Online (Sandbox Code Playgroud)

一切正常。

更疯狂的是,如果我“组合”这两个 import matplotlib as mpl from matplotlib import pyplot as plt #works!mpl.pyplot.get_backend() # 有效

pyplot即使我将其引用为 ,我也可以好奇地访问属性mpl.pyplot

这是怎么回事,为什么

  • from mpl import pyplot as plt抛出一个ModuleNotFoundError

  • import mpl.pyplot不行?由于错误消息表明mpl已正确解析为matplotlib,但仍然pyplot找不到...

  • 在我的上一个示例中引用pyplot不会mpl.pyplot导致错误?

(请注意,我当然知道首选方法是导入pyplotas import matplotlib.pyplot as plt,但我调查的目的正是为了了解当我冒险走出常见的代码街道时失败的原因以及失败的原因。)

l4m*_*mpi 9

import 语句中的部分as只是语法糖,用于将导入的模块分配给具有给定名称的变量。文档import这样描述的:

如果模块名称后跟 as,则 as 后面的名称将直接绑定到导入的模块。

在这种情况下,“绑定”意味着对给定名称进行赋值。以下声明

import someModule as someName
Run Code Online (Sandbox Code Playgroud)

相当于这段代码:

import someModule
someName = someModule
Run Code Online (Sandbox Code Playgroud)

因此,当您这样做时import matplotlib as mpl,您所做的就是创建一个名为 的变量mpl。这对任何进一步的 import 语句都没有影响,因为 import 语句不关心本地变量,而是搜索 python 包和模块 - 并且语句import as不能更改导入元素的包或模块名称。这是一件好事,因为您不希望 import 语句仅仅因为 5 行之前的另一个 import 在子句中使用了冲突的名称而失败as

现在,为什么你的声明会得到奇怪的结果import mpl.pyplot- 不知道,它不应该起作用。如果尝试以下操作,您可以看到预期的行为:

import os as asdf
import asdf.path    #ModuleNotFoundError: no module named 'asdf'
Run Code Online (Sandbox Code Playgroud)

在 Archlinux 上使用 python 3.10.2 进行测试。如果你的例子是可重现的,那么你可能在你的特定Python版本中发现了一个奇怪的错误或未定义的行为,或者有一些其他问题(例如mpl你的路径中的模块......尽管这本身并不能解释为什么你会得到有关 matplotlib 而不是 mpl 的错误消息)。

总之,所做的as只是为导入的对象分配一个名称,因此分配的名称as不能用作另一个导入语句中的源。


关于包导入以及为什么matplotlib.pyplot会出现错误:

导入包仅导入包本身,而不导入其任何子包或模块。包可以在其 中显式导入子模块__init__.py,因此如果 matplotlib 初始化文件包含像from . import pyplotline 这样的语句,则访问matplotlib.pyplot将起作用。然而,包可能选择不导入任何子模块的原因有很多,例如导入和初始化它们所需的时间和资源。