2009-12-24 35 views
8

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

它确实看起来像是新的“绝对导入”支持(新的Python 2.5以上版本)的bug或未公开的行为。试着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'> 

为“子,名”双输出表明,我自己的子包称为“记录”是进口本身是第二次,即使“absolute_import”已启用,也找不到stdlib“logging”包

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

任何想法正在发生,无论这是一个错误(我的还是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'> 

回答

10

sys.path[0]默认情况下'',这意味着“当前目录”。所以,如果你坐在一个logging的目录里,那将会首先被选中。

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

+0

谢谢。我刚刚意识到这一点,因为我在午餐时更多地考虑了这一点。我想这是不可避免的,除非你故意删除sys.path [0]或者将''移动到最后或者其他东西。我会在我的问题中注意到这一点。 – 2009-12-24 18:03:35