Python 2.7中“绝对导入”的正确方法

时间:2015-11-24 12:21:07

标签: python python-2.7 python-import

  • Python 2.7.10
  • 在virtualenv
  • 在每个模块中启用from __future__ import absolute_import

目录树如下所示:

Project/
    prjt/
        __init__.py
        pkg1/
            __init__.py
            module1.py
            tests/
                __init__.py
                test_module1.py
        pkg2/
            __init__.py
            module2.py
            tests/
                __init__.py
                test_module2.py
        pkg3/
            __init__.py
            module3.py
            tests/
                __init__.py
                test_module3.py
    data/
    log/

我尝试在compute()中使用pkg2/module2.py的函数pkg1/module1.py写成:

# In module1.py
import sys
sys.path.append('/path/to/Project/prjt')

from prjt.pkg2.module2 import compute

但是当我运行python module1.py时,解释器引发了No module named prjt.pkg2.module2的ImportError。

  1. “绝对导入”的正确方法是什么?我是否必须将Project的路径添加到sys.path
  2. 我怎样才能在交互式口译员中运行test_module1.py?按python prjt/pkg1/tests/test_module1.pypython -m prjt/pkg1/tests/test_module1.py

5 个答案:

答案 0 :(得分:15)

python如何找到模块

python会从sys.path找到模块,第一个条目sys.path[0]是''意思是,python将从当前工作目录中找到模块

import sys
print sys.path

和python从site-packages

中找到第三方模块

所以要绝对导入,你可以

将您的包附加到sys.path

import sys
sys.path.append('the_folder_of_your_package')

import module_you_created

module_you_created.fun()

导出PYTHONPATH

PYTHONPATH将在执行前导入到sys.path中

export PYTHONPATH=the_folder_of_your_package

import sys
[p for p in sys.path if 'the_folder_of_your_package' in p]
  

我怎样才能在交互式解释器中运行test_module1.py?通过python Project / pkg1 / tests / test_module1.py或python -m Project / pkg1 / tests / test_module1.py?

您可以使用if __name__ == '__main__':惯用法,并使用python Project/pkg1/tests/test_module1.py

if __name__ = '__main__':
    main()

答案 1 :(得分:7)

如果您将sys.path.append('path/to/Project')添加到prjt/__init__.py,则需要导入子模块,因此:from pkg2.module2 import compute(不含prjt规范)因为prjt包导入正在进行中并且更高级别的文件夹不在sys.path中。这正是@Cissoid所建议的。

顺便说一下,Py> = 2.6不需要from __future__ import absolute_import

回答你的第二个问题...我对unittests子文件夹的结构非常相似,所以在pkg/unittests/testall.py我写了以下内容:

testfolder = os.path.abspath(os.path.dirname(__file__))
project_root = os.path.abspath(os.path.join(testfolder, r"..\.."))
sys.path.append(project_root)
import pkg

我在没有-m选项的情况下运行它,因为这是不必要的复杂化。

答案 2 :(得分:6)

导入外部项目路径。

sys.path.append('/path/to/Project')

或从pkg2

开始导入“compute”
from pkg2.module2 import compute

答案 3 :(得分:2)

试试这个

import os, sys
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))

这将给出绝对路径

答案 4 :(得分:0)

使用显式相对导入,这应该从module1.py开始工作:

from ..pkg2.module2 import compute()

这比弄乱PYTHONPATH ...