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

Zel*_*ong 27 python python-import python-2.7

  • 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/
Run Code Online (Sandbox Code Playgroud)

我试图用功能compute()pkg2/module2.pypkg1/module1.py写,如:

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

from prjt.pkg2.module2 import compute
Run Code Online (Sandbox Code Playgroud)

但是当我跑步时python module1.py,解释器引发了一个ImportError No module named prjt.pkg2.module2.

  1. 什么是"绝对导入"的正确方法?我一定要添加路径到Projectsys.path
  2. 我怎么能test_module1.py在交互式翻译中运行?通过python prjt/pkg1/tests/test_module1.pypython -m prjt/pkg1/tests/test_module1.py

Sea*_*ean 15

python如何查找模块

python将从中找到模块sys.path,并且第一个条目sys.path[0]是''表示,python将从当前工作目录中找到模块

import sys
print sys.path
Run Code Online (Sandbox Code Playgroud)

和python从中找到第三方模块 site-packages

所以要绝对导入,你可以

将你的包裹附加到 sys.path

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

import module_you_created

module_you_created.fun()
Run Code Online (Sandbox Code Playgroud)

出口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]
Run Code Online (Sandbox Code Playgroud)

我怎么能在交互式解释器中运行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()
Run Code Online (Sandbox Code Playgroud)


Vas*_*bov 7

如果添加sys.path.append('path/to/Project')prjt/__init__.py,您需要导入子模块这样:from pkg2.module2 import compute(不prjt规范),因为prjt包导入过程中和上级文件夹不在sys.path.这正是@Cissoid所建议的.

from __future__ import absolute_importPy> = 2.6不需要BTW .


回答你的第二个问题......我对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
Run Code Online (Sandbox Code Playgroud)

我没有-m选项运行它,因为它是不必要的复杂性.

  • 只是:`from __future__ import absolute_import`是不必要的,因为python> = 3.0,之前它仍然需要/制作差异. (3认同)

小智 6

导入外部项目路径.

sys.path.append('/path/to/Project')
Run Code Online (Sandbox Code Playgroud)

或者从pkg2开始导入"compute"

from pkg2.module2 import compute
Run Code Online (Sandbox Code Playgroud)