Python 同名的相对导入和绝对导入导致;属性错误:';模块';对象没有属性…”;

Python 同名的相对导入和绝对导入导致;属性错误:';模块';对象没有属性…”;,python,python-2.7,python-import,Python,Python 2.7,Python Import,使用以下代码: foo.py: #!/usr/bin/env python import package package.go() from __future__ import absolute_import import logging from .logging import config def go(): config(level=logging.DEBUG) logging.getLogger().debug('this is a test') from __fu

使用以下代码:

  • foo.py

    #!/usr/bin/env python
    import package
    package.go()
    
    from __future__ import absolute_import
    import logging
    from .logging import config
    def go():
        config(level=logging.DEBUG)
        logging.getLogger().debug('this is a test')
    
    from __future__ import absolute_import
    import logging
    def config(*args, **kwargs):
        return logging.basicConfig(*args, **kwargs)
    
  • package/\uuuuuu init\uuuuuuuuuuuuuupy

    #!/usr/bin/env python
    import package
    package.go()
    
    from __future__ import absolute_import
    import logging
    from .logging import config
    def go():
        config(level=logging.DEBUG)
        logging.getLogger().debug('this is a test')
    
    from __future__ import absolute_import
    import logging
    def config(*args, **kwargs):
        return logging.basicConfig(*args, **kwargs)
    
  • package/logging.py

    #!/usr/bin/env python
    import package
    package.go()
    
    from __future__ import absolute_import
    import logging
    from .logging import config
    def go():
        config(level=logging.DEBUG)
        logging.getLogger().debug('this is a test')
    
    from __future__ import absolute_import
    import logging
    def config(*args, **kwargs):
        return logging.basicConfig(*args, **kwargs)
    
我得到以下错误:

$。/foo.py
回溯(最近一次呼叫最后一次):
文件“/foo.py”,第3行,在
打包
文件“/tmp/test/package/_init__.py”,第5行,在go中
配置(级别=logging.DEBUG)
AttributeError:“模块”对象没有“调试”属性
这就好像.logging import config行中的
正在导入
。logging
logging
,即使我不希望这样

如果我交换
package/_init_uuu.py
中的导入行,使其如下所示:

from __future__ import absolute_import
from .logging import config
import logging
def go():
    config(level=logging.DEBUG)
    logging.getLogger().debug('this is a test')
然后它就起作用了:

$。/foo.py
调试:根:这是一个测试

原版有什么问题?或者这是Python 2.7.8中的一个bug?

包中的模块一旦导入,就会被设置为其父包上的属性

导入
.logging
时,它会被添加到
包的
命名空间中,例如在
包的
目录的
globals()
字典中

通过交换导入,您可以将
\uuuuu init\uuuuu
模块命名空间中的
日志记录
全局重新替换为顶级包;首先导入子模块并将其添加到全局,然后导入
日志记录
包,替换全局

演示:

$mkdir包
$cat>package/\uuuuuu init\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
>从.logging导入foo
>打印全局参数().keys()
>打印日志
>导入日志记录
>打印全局参数().keys()
>打印日志
>EOF
$cat>package/logging.py foo='bar'
>打印“导入的包。日志记录”
>EOF
$python-c“导入包”
已导入包日志记录
['logging'、'uuuuu builtins'、'uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
['logging'、'uuuuu builtins'、'uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

.logging
包导入
foo
后,将立即显示
logging
全局。导入顶级
日志记录
包,然后重新绑定名称。

您知道文档中描述此行为的地方吗?@RichardHansen:正在查找;老实说,包装进口的文件记录有点不足。@RichardHansen:不幸的是,我现在找不到一份好的参考资料给你;我已经添加了此问题的演示,现在您必须相信我的话,子模块在导入时会添加到父包的全局。我也找不到任何有关此问题的文档:(