为什么Python模块有时不导入它们的子模块?

为什么Python模块有时不导入它们的子模块?,python,python-import,Python,Python Import,我今天注意到一些奇怪的事情,我想解释一下。我甚至不能100%确定如何把这当作一个问题来表达,所以谷歌是不可能的。由于某些奇怪的原因,日志记录模块无法访问模块logging.handlers。如果你不相信我,你自己试试看: >>> import logging >>> logging.handlers Traceback (most recent call last): File "<stdin>", line 1, in <module&

我今天注意到一些奇怪的事情,我想解释一下。我甚至不能100%确定如何把这当作一个问题来表达,所以谷歌是不可能的。由于某些奇怪的原因,日志记录模块无法访问模块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'>
导入日志记录 >>>日志处理程序 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 AttributeError:“模块”对象没有属性“处理程序” >>>导入日志记录处理程序 >>>日志处理程序
有人能解释为什么会发生这种情况吗?

在Python中,模块需要先导入才能访问<代码>导入日志记录仅导入日志记录模块。碰巧,
日志记录
是一个包含子模块的包,但这些子模块仍然不会自动加载。因此,您需要显式导入
logging.handlers
,然后才能访问它


如果您想知道为什么有时候您不需要这些额外的导入:一些包在导入时导入其部分或全部子模块——只需在其
\uuuuu init\uuuuuuuuuy.py
文件中进行这些导入即可。在其他情况下,可能是您导入的其他内容也导入了
logging.handlers
。导入哪段代码并不重要;只要流程中的某些内容在您访问它之前导入
logging.handlers
,它就会存在。有时看起来像包的模块实际上不是包,比如
os
os.path
os
不是一个包,它只是导入正确的其他模块(适用于您的平台)并调用它
path
,这样您就可以作为
os.path
访问它。我也是python新手,经过大量实践,现在我可以区分, 包(文件夹)、模块(.py)、类、变量等

如果你想让你的任何文件夹成为python包,它必须包含
\uuuu init\uuuu.py
文件,即使是空文件也可以

正如Thomas所说,如果您愿意,您可以在
\uuuu init\uuuu.p
y中导入额外的模块!!!但是模块/包只有在导入后才能访问

如果要从模块导入所有内容,可以使用

from logging import *
rest您也可以访问如下所示的处理程序模块

from logging import handlers
print dir(handlers)

我最近遇到了同样的奇怪情况。所以,我打赌你已经删除了一些第三方库导入。删除了所包含的lib
来自日志导入处理程序
来自日志导入*
并提供给您
处理程序
。在另一个脚本中,您使用了类似于
import logging
的东西,并且只使用了
logging.handlers
,您认为这是一种工作方式,就像我所做的那样

很好地回答了这个问题,但唉,我只是在原始文档中找到答案后才发现这个问题。为此,我想我会加上这个,希望它在未来更接近搜索引擎的顶端

问题 为什么会出现错误:“属性错误:模块“模块名称”没有属性“子模块名称” 虽然我的编辑器(例如视觉代码)自动完成子模块 姓名:

回答 编辑器的自动完成基于项目的文件结构,而不是Python行为。子模块不可用 导入模块时“自动”导入。有关使用时如何“自动”导入子模块的详细信息,请参阅

这个答案的主要贡献是在尝试导入“模块”或“包”时添加了AttributeError


希望这对别人有帮助

请不要使用模块导入中的
*
。这几乎总是一个错误。如果您希望自动导入包中的所有内容,请在init.py中进行这些导入,而不是在init.py中设置all并在某处执行“从包导入*”。@Pete:因为它“污染”了标准名称空间,从而导致歧义和冲突。如果我有
import-zippers
zippers.open()
你就会确切知道我调用的是哪个open。相反,拉链导入的
后接
open()
是内置的open还是zipper.open或其他东西<如果您厌倦了键入
zippers
,则最好使用code>import zippers as z
。@Pete:这也是一个问题,因为您可能会在不知不觉中覆盖某些名称空间。我过去经常使用from
numpy import*
,因为有些numpy函数除非导入所有的numpy(在我看来是可怕的设计缺陷),否则无法工作,但是numpy导入了大量的对象。我最终覆盖了很多函数(我相信复制就是其中之一……我太累了,无法检查)。现在,如果我打算大量使用numpy,以致于无法忍受反复键入它,我会将numpy作为np导入。@dustynachos,哪个numpy函数有这个缺陷?
 import module_name
 module_name.sub_module_name(parameter)
 import module_name