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

我今天注意到一些奇怪的事,我想解释一下。我甚至不能百分之百确定如何将这个问题形容为一个问题,所以谷歌是不可能的。由于某些奇怪的原因,日志模块不能访问模块 logging.handler。如果你不相信我,你自己试试:

>>> 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'>

有人能解释一下为什么会这样吗?

28214 次浏览

In Python, modules need to be imported before they're accessible. import logging imports just the logging module. It so happens that logging is a package with submodules, but those submodules are still not automatically loaded. So, you need to explicitly import logging.handlers before you can access it.

If you're wondering why it looks like sometimes you don't need those extra imports: some packages import some or all of their submodules when they are imported -- simply by doing those imports in their __init__.py files. In other cases it might be that something else that you import, also imported logging.handlers. It doesn't matter which piece of code does the import; as long as something in your process imports logging.handlers before you access it, it'll be there. And sometimes a module that looks like a package really isn't one, like os and os.path. os isn't a package, it just imports the correct other module (for your platform) and calls it path, just so you can access it as os.path.

I'm also new to python and after having lots of practice now I can differentiate between, package (folder) , module(.py) , classes,variables...etc...

if you want any of your folder to be python package - It must contain __init__.py file even empty file will do !!!

and as Thomas said, you can import extra module in __init__.py if you want !!! but modules/packages are accessible only after importing it...

if you want to import everything from a module you can use

from logging import *

rest you can access the handlers module like below too,

from logging import handlers
print dir(handlers)

I've faced recently the same odd situation. So, I bet you've removed some third-party lib import. That removed lib contained from logging import handlers or from logging import * and provided you handlers. And in other script you've had something like import logging and just used logging.handlers and you've thought that is a way things work as I did.

Thomas Wouters answered this question very well, but alas, I only found this question after finding the answer in the original documentation. To that end I thought I would add to this in the hopes it pops up closer to the top of the search engine in the future.

QUESTION

Why does the error: 'AttributeError: module 'module_name' has no attribute 'sub_module_name' appear even though my editor (e.g. Visual Code) auto-completes the sub-module name:

 import module_name
module_name.sub_module_name(parameter)

ANSWER

Your editor is basing its autocomplete off of the file structure of your project and not off of Python behavior. Sub-modules are not 'automatically' imported when you import a module. Reference Python Documentation for details on how to 'automatically' import sub-modules when using

 import module_name

The key contribution with this answer being the addition of AttributeError when trying to import a 'module' or 'package'

Hope this helps someone!