【问题标题】:What is the correct way to import modules in python library?在 python 库中导入模块的正确方法是什么?
【发布时间】:2013-12-26 10:55:59
【问题描述】:

当你编写一个 python 库,并想从另一个模块中导入一个模块时,正确的方法是什么,以便在从外部导入库和运行某些单元测试时导入工作库目录?

如果你这样做

import some_module
from some_module import something

从库目录运行时它可以工作,但从外部导入时会产生ImportError: No module named 'some_module'

你可以的

from . import some_module
import my_library.some_other_module
from .some_module import something

但是如果你从放在同一目录中的单元测试中导入库,它将不起作用。

最后,您可以使用sys.path 和/或将单元测试移至其他目录。

什么是最好的解决方案?

编辑:为了清楚起见,我想在库的顶层目录中使用python -m unittest 运行单元测试。到目前为止,我通过添加使其工作

import os
import sys
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

到单元测试文件的开头。作为替代方案,可以编写一个简短的 shell 脚本,将父目录添加到PYTHONPATH,然后运行单元测试。不知道有没有更好的处理方法?

【问题讨论】:

  • PYTHONPATH而不是sys.path也许...
  • 我发现您的问题难以理解且令人困惑。你能澄清一下你实际上做了什么吗?我的猜测是,当您实际需要在库的外部 进行单元测试时,您在库的inside 中进行了单元测试。即,$ ls . 应该显示您的库目录。

标签: python


【解决方案1】:

查看Module Search Path上的文档

当一个名为 spam 的模块被导入时,解释器首先搜索 对于具有该名称的内置模块。如果没有找到,然后搜索 对于一个名为 spam.py 的文件,在由 变量 sys.path。 sys.path 从这些位置初始化:

  • 包含输入脚本的目录(或当前目录)。
  • PYTHONPATH(目录名称列表,与 shell 变量 PATH 语法相同)。
  • 依赖于安装的默认值。

如果您编写库,测试代码通常应该以与库用户相同的方式与库交互。这可能意味着通过设置 PYTHONPATH 环境变量或将模块安装在默认的 3rd 方模块位置,将模块添加到搜索路径。

我建议使用自动测试发现选项从包含模块的基本目录运行测试

python -m unittest discover (python >= 2.7)

这将递归查找匹配 test_*.py 的文件(即在模块目录中),但应设置相对于父目录的 python 路径。

【讨论】:

  • 从父目录运行单元测试听起来不是一个好的解决方案,因为它会扫描父目录中所有不相关的子目录。
  • 当你导入一个模块时,Python 会搜索这些相同的目录,所以如果你的 python 搜索路径中有多余的文件,可能需要进行重组。在实践中,大多数项目的搜索几乎是即时的。您还可以从父目录运行特定模块,例如 python -m foo.tests.test_bar
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-14
  • 2020-09-14
  • 1970-01-01
  • 2015-11-22
  • 2011-09-16
  • 2020-04-09
相关资源
最近更新 更多