绝对导入在subpackage中失败,影响stdlib包名称

时间:2009-12-24 17:46:34

标签: python import

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

它看起来像是一个bug,或者是新的“绝对导入”支持的无证行为(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”第二次导入自身,并且即使启用了“absolute_import”,它也找不到stdlib“logging”包 / em>的

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

任何想法发生了什么,这是一个bug(我的还是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'>

1 个答案:

答案 0 :(得分:10)

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

我最近遇到了这个问题,直到我意识到我确实坐在那个目录中,sys.path正在查看我当前的目录,然后查看标准库。