为什么Python模块有时不导入其子模块?

99 投票
4 回答
28726 浏览
提问于 2025-04-16 04:31

今天我发现了一些奇怪的事情,想请人解释一下。我不太确定该怎么问这个问题,所以也没法在谷歌上查。奇怪的是,日志模块(logging)居然无法访问日志处理器模块(logging.handlers)。如果你不相信,可以自己试试:

>>> import logging
>>> logging.handlers
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'handlers'
>>> import logging.handlers
>>> logging.handlers
<module 'logging.handlers' from '/usr/lib/python2.6/logging/handlers.pyc'>

有没有人能解释一下这是为什么呢?

4 个回答

4

Thomas Wouters 对这个问题的回答非常好,不过可惜的是,我是在找到原始文档的答案后才发现这个问题的。为了让这个信息更容易被找到,我想补充一些内容,希望它能在搜索引擎中更靠前。

问题

为什么会出现错误:'AttributeError: module 'module_name' has no attribute 'sub_module_name',即使我的编辑器(比如 Visual Code)能自动补全子模块的名字呢?

 import module_name
 module_name.sub_module_name(parameter)

答案

你的编辑器是根据你项目的文件结构来进行自动补全的,而不是根据 Python 的行为。当你导入一个模块时,子模块并不会'自动'被导入。想了解如何在使用时'自动'导入子模块,可以参考 Python 文档

 import module_name

这个答案的关键在于,当尝试导入一个'模块'或'包'时,可能会出现 AttributeError。

希望这能帮助到某些人!

4

我也是刚开始学Python,经过很多练习,现在我能区分包(文件夹)、模块(.py文件)、类、变量等等。

如果你想让某个文件夹变成Python包,它里面必须有一个__init__.py文件,哪怕这个文件是空的也可以!!!

正如Thomas所说,如果你想的话,可以在__init__.py文件里导入其他模块!!!不过模块或包只有在导入后才能使用……

如果你想从一个模块中导入所有内容,可以使用

from logging import *

其余的,你也可以像下面这样访问处理程序模块,

from logging import handlers
print dir(handlers)

127

在Python中,模块在使用之前需要先导入。比如,import logging 这行代码就是导入了日志模块。其实,logging 是一个包含子模块的包,但这些子模块并不会自动加载。所以,你需要明确地导入 logging.handlers,才能使用它。

如果你在想为什么有时候看起来不需要额外的导入:有些包在被导入时,会自动导入它们的一些或全部子模块,这通常是在它们的 __init__.py 文件里完成的。在其他情况下,可能是你导入的某个东西也导入了 logging.handlers。其实,谁来做这个导入并不重要;只要在你使用 logging.handlers 之前,有哪个代码导入了它,它就会存在。有时候,看起来像包的模块其实并不是,比如 osos.pathos 其实不是一个包,它只是导入了适合你平台的其他模块,并把它叫做 path,这样你就可以通过 os.path 来访问它。

撰写回答