首先,假设标题为mypackage
的Python包的以下目录结构遵循指南How To Package Your Python Code的说明:
mypackage/
mypackage/mypackage/
mypackage/mypackage/__init__.py
mypackage/mypackage/a_function.py
mypackage/scripts/
mypackage/scripts/a_script.py
mypackage/tests/
mypackage/tests/a_function_test.py
mypackage/misc/
mypackage/misc/input.txt
# mypackage/misc/actual_output.txt ## Not yet generated!
mypackage/misc/expected_output.txt
mypackage/setup.py
其次,假设脚本a_script.py
导入a_function.py
,读取文件input.txt
,操纵input.txt
的内容并将后者保存为actual_output.txt
mypackage/misc/
。
第三,假设unittest模块mypackage/misc/
包含一个测试函数,用于通过expected_output.txt
将actual_output.txt
与self.assertMultiLineEqual(expected, actual)
进行比较。
最后,假设我想通过python2 setup.py test
运行unittest模块。
如何在actual_output.txt
中指定expected_output.txt
和a_function_test.py
的位置而不对其绝对文件路径进行硬编码(因此,阻止我的包的任何可转移性)?
代价:
理论上,我可以将包内路径硬编码到两个输入文件中的每一个。但是,如果mypackage
尚未安装site-packages
,那么Python解释器如何知道在哪里查找?我有以下想法,但由于mypackage
还不知道而失败了:
base_path = os.path.split(inspect.getfile(mypackage))[0]
within_path = mypackage/misc/
expected = open(base_path + within_path + expected_output.txt).read()
actual = open(base_path + within_path + actual_output.txt).read()
self.assertMultiLineEqual(expected, actual)
答案 0 :(得分:0)
从a_script.py
,你可以像这样进入主mypackage
:
mypackage_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
或:
mypackage_dir = os.path.dirname(os.path.abspath(__package__))
然后,可以构建其他路径,因为您知道子包的名称:
misc_dir = os.path.join(mypackage_dir, 'misc')
tests_dir = os.path.join(mypackage_dir, 'tests')