另一个绝对导入问题
我在使用自己的模块时遇到了问题,它们覆盖了Python自带的模块(特别是日志模块)。这是我的项目结构:
run.py
package/
__init__.py
logging/
__init__.py
...
run.py
from package import main
main()
package/__init__.py
from __future__ import absolute_import
import logging
import logging.config
def main():
logging.config.fileConfig(...)
package/logging/__init__.py
class Logging(object):
pass
目前为止,上面的代码是可以正常工作的。但是当我尝试像这样从package.logging导入Logging类时:
from __future__ import absolute_import
import logging
import logging.config
from package.logging import Logging
def main():
logging.config.fileConfig(...)
我就会遇到一个错误:
AttributeError: 'module' object has no attribute 'config'
我看过PEP 328的发布说明,发现绝对导入其实挺简单的。不过,我还是没能搞明白这个问题出在哪里。
我漏掉了什么呢?
2 个回答
1
9
相对导入和绝对导入(PEP 328)在这里并不是问题。
发生的情况是,当你导入一个包中的模块时,这个模块会自动被添加到这个包的命名空间里。所以
from package.logging import Logging
不仅会把 'Logging' 加入到包的 _dict 中,还会把 'logging'(新导入的本地模块)也加入到包的 _dict 中。这样一来,你首先导入了 logging(顶层模块),它可以通过 package.logging 来访问,然后你又用本地模块覆盖了这个变量。这基本上意味着,你不能像预期那样同时通过 package.logging 来访问顶层模块和你的本地模块。
在这个特定的情况下,你可能并不想把顶层的 logging 模块作为公共名称“导出”。相反,你可以这样做:
from logging import config as _config
def main():
_config.fileConfig(...)