为什么Python模块有时不导入其子模块?
今天我发现了一些奇怪的事情,想请人解释一下。我不太确定该怎么问这个问题,所以也没法在谷歌上查。奇怪的是,日志模块(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 个回答
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。
希望这能帮助到某些人!
我也是刚开始学Python,经过很多练习,现在我能区分包(文件夹)、模块(.py文件)、类、变量等等。
如果你想让某个文件夹变成Python包,它里面必须有一个__init__.py
文件,哪怕这个文件是空的也可以!!!
正如Thomas所说,如果你想的话,可以在__init__.py
文件里导入其他模块!!!不过模块或包只有在导入后才能使用……
如果你想从一个模块中导入所有内容,可以使用
from logging import *
其余的,你也可以像下面这样访问处理程序模块,
from logging import handlers
print dir(handlers)
在Python中,模块在使用之前需要先导入。比如,import logging
这行代码就是导入了日志模块。其实,logging
是一个包含子模块的包,但这些子模块并不会自动加载。所以,你需要明确地导入 logging.handlers
,才能使用它。
如果你在想为什么有时候看起来不需要额外的导入:有些包在被导入时,会自动导入它们的一些或全部子模块,这通常是在它们的 __init__.py
文件里完成的。在其他情况下,可能是你导入的某个东西也导入了 logging.handlers
。其实,谁来做这个导入并不重要;只要在你使用 logging.handlers
之前,有哪个代码导入了它,它就会存在。有时候,看起来像包的模块其实并不是,比如 os
和 os.path
。os
其实不是一个包,它只是导入了适合你平台的其他模块,并把它叫做 path
,这样你就可以通过 os.path
来访问它。