根据@mgilson 的评论,我import_helper.py
在测试目录中添加了一个文件。
some_dir/
mod.py
test/
test_mod.py
import_helper.py
example_data.txt
以下是 的内容import_helper.py
:
import sys as _sys
import os.path as _ospath
import inspect as _inspect
from contextlib import contextmanager as _contextmanager
@_contextmanager
def enable_parent_import():
path_appended = False
try:
current_file = _inspect.getfile(_inspect.currentframe())
current_directory = _ospath.dirname(_ospath.abspath(current_file))
parent_directory = _ospath.dirname(current_directory)
_sys.path.insert(0, parent_directory)
path_appended = True
yield
finally:
if path_appended:
_sys.path.pop(0)
然后在导入部分test_mod.py
,在尝试导入之前mod.py
,我添加了:
import unittest
from import_helper import enable_parent_import
with enable_parent_import():
from mod import some_mod_function_to_test
不幸的是需要手动修改 PYTHONPATH,但是将其编写为上下文管理器会有所帮助,并且可以恢复sys.path
到父目录修改之前的原始状态。
为了使此解决方案能够跨此问题的多个实例进行扩展(比如明天我被要求widget.py
为一些不相关的任务编写一个模块,并且它也不能作为一个包分发),我必须复制我的辅助函数并确保复制它与任何测试一起分发,或者我必须将该小实用程序编写为一个包,确保它在我的用户群中全局安装,然后继续维护它。
当您在公司内部管理大量 Python 代码时,通常会出现一种功能失调的代码分发模式,即“安装”一些 Python 代码相当于从版本控制中签出新版本。
由于代码通常非常本地化并且特定于较大团队的一小部分任务的一小部分任务,因此通过打包来维护共享代码的开销(即使它通常是一个更好的想法)根本不会发生。
因此,我觉得我上面描述的用例对于现实世界的 Python 来说非常普遍,如果一些导入工具添加了这个功能来修改 PYTHONPATH,那就太好了,一些明智的默认选择(比如添加父目录)非常简单的。
这样,您至少可以依赖它作为标准库的一部分,而无需滚动您自己的代码并确保它与您的测试一起提供或安装在您的用户群中。