【问题标题】:What's the order Python used to import module?Python 用于导入模块的顺序是什么?
【发布时间】:2015-10-29 05:23:56
【问题描述】:

我遇到了关于 python 导入语句的一些奇怪的事情。

假设我的文件结构如下:

foo\
    __init__.py
    bar.py
    os.py

bar.py 中的代码(其他文件为空)

import os
print os.__file__

奇怪的是,当我运行 python -m foo.bar 时,它会打印出来

foo/os.pyc

但是,当我将目录更改为 foo 并运行 python -m bar 时,它会打印出来

/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc

我运行脚本的两种方式有什么区别?

一句话,Python 导入模块的顺序是什么?

从官方文档中,我找到了几个关于这个问题的文字(他们让我更加困惑)

  1. 6.1.2. The Module Search Path

解释器首先搜索具有该名称的内置模块。如果没有找到,它会在由变量 sys.path 给出的目录列表中搜索名为 spam.py 的文件。

  1. sys.path

此列表的第一项路径 [0] 是包含用于调用 Python 解释器的脚本的目录。如果脚本目录不可用(例如,如果交互调用解释器或从标准输入读取脚本),path[0] 是空字符串,它指示 Python 首先搜索当前目录中的模块。

  1. 6.4.2. Intra-package References

事实上,此类引用非常普遍,以至于 import 语句首先在 包含包 中查找,然后再查找 标准模块 搜索路径。

...

如果在当前包(当前模块是其子模块的包)中找不到导入的模块,则导入语句会查找具有给定名称的顶级模块

【问题讨论】:

    标签: python python-2.7 import module


    【解决方案1】:

    我运行脚本的两种方式有什么区别?

    区别在于foo 是否(从 python 的角度)是加载的模块。

    如果你运行python -m foo.barfoo 是一个有效的模块。即使使用 Python 2.7,import os 仍然是 relative import,因此 os 会针对包含模块(即 foo)进行解析,首先:

    https://docs.python.org/2/tutorial/modules.html#intra-package-references:

    子模块经常需要相互引用。例如,环绕模块可能使用回声模块。事实上,这种引用非常普遍,以至于 import 语句首先在包含包中查找,然后再查找标准模块搜索路径。

    当您运行python -m bar 时,bar 是顶级模块,即它没有包含模块。在这种情况下,import os 会通过 sys.path

    import bla 的默认模块搜索是

    1. 如果存在包含模块,请针对包含模块执行相对导入。
    2. 进入sys.path 并使用第一个成功的导入。

    要禁用 (1),您可以

    from __future__ import absolute_import  
    

    在模块的最顶端。

    令人困惑?绝对的。

    【讨论】:

    • [包含包]> 内置模块> sys.path
    猜你喜欢
    • 1970-01-01
    • 2018-07-30
    • 2022-12-09
    • 2012-03-07
    • 1970-01-01
    • 2018-04-16
    • 1970-01-01
    • 2014-01-23
    相关资源
    最近更新 更多