【问题标题】:Absolute import failing in subpackage that shadows a stdlib package name隐藏 stdlib 包名称的子包中的绝对导入失败
【发布时间】:2009-12-24 17:46:34
【问题描述】:

基本上,我有一个与标准库包(“日志记录”)同名的子包,我希望它能够绝对导入标准的,无论我如何运行它,但是当我失败时'm 在父包中。

它看起来像是一个错误,或者是新的“绝对导入”支持(Python 2.5 的新功能)的未记录行为。尝试使用 2.5 和 2.6。

包装布局:

foo/
    __init__.py
    logging/
        __init__.py

foo/__init__.py 我们导入我们自己的日志子包:

from __future__ import absolute_import
from . import logging as rel_logging
print 'top, relative:', rel_logging

foo/logging/__init__.py 我们要导入stdlib logging 包:

from __future__ import absolute_import
print 'sub, name:', __name__

import logging as abs_logging
print 'sub, absolute:', abs_logging

注意:包含foo的文件夹在sys.path中。


当从foo外部/上方导入时,输出如预期:

c:\> python -c "import foo"
sub, name: foo.logging
sub, absolute: <module 'logging' from 'c:\python26\lib\logging\__init__.pyc'>
top, relative: <module 'foo.logging' from 'foo\logging\__init__.pyc'>

所以子包中的绝对导入会根据需要找到stdlib包。

但是当我们在 foo 文件夹中时,它的行为会有所不同:

c:\foo>\python25\python -c "import foo"
sub, name: foo.logging
sub, name: logging
sub, absolute: <module 'logging' from 'logging\__init__.pyc'>
sub, absolute: <module 'logging' from 'logging\__init__.pyc'>
top, relative: <module 'foo.logging' from 'c:\foo\logging\__init__.pyc'>

“sub, name”的双重输出表明我自己的名为“logging”的子包正在第二次导入自己,它没有找到stdlib“logging”包即使启用了“absolute_import”。

用例是,无论当前目录是什么,我都希望能够使用、测试等这个包。将名称从“记录”更改为其他名称是一种解决方法,但不是理想的解决方法,而且无论如何这种行为似乎不符合绝对导入应该如何工作的描述。

知道发生了什么,这是一个错误(我的还是 Python 的),还是某些文档实际上暗示了这种行为?

编辑: gahooa 的回答清楚地表明了问题所在。这里显示了一个粗略的解决方法来证明就是这样:

c:\foo>python -c "import sys; del sys.path[0]; import foo"
sub, name: foo.logging
sub, absolute: <module 'logging' from 'c:\python26\lib\logging\__init__.pyc'>
top, relative: <module 'foo.logging' from 'c:\foo\logging\__init__.pyc'>

【问题讨论】:

    标签: python import


    【解决方案1】:

    sys.path[0] 默认为'',表示“当前目录”。因此,如果您坐在包含logging 的目录中,则会首先选择它。

    我最近遇到了这个问题,直到我意识到我实际上是坐在那个目录中,并且 sys.path 在查看标准库之前首先选择了我的当前目录。

    【讨论】:

    • 谢谢。我刚刚意识到这一点,因为我在午餐时更多地思考了这一点。我想这是不可避免的,除非您故意删除 sys.path[0] 或将 '' 移到末尾或其他东西。我会在我的问题中指出这一点。
    猜你喜欢
    • 1970-01-01
    • 2017-09-23
    • 2017-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-28
    • 2017-08-08
    • 2019-12-07
    相关资源
    最近更新 更多