Во-первых, предположим следующую структуру каталогов пакета Python под названием mypackage
, которая следует инструкциям руководства Как упаковать код Python. а>:
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)
.
Наконец, предположим, что я хочу запустить модуль unittest через python2 setup.py test
.
Как указать расположение actual_output.txt
и expected_output.txt
в a_function_test.py
без жесткого кодирования их абсолютных путей к файлам (и, следовательно, предотвращения возможности передачи моего пакета)?
Рассмотрение:
Теоретически я могу жестко указать путь внутри пакета к каждому из двух входных файлов. Однако как интерпретатор Python узнает, где искать mypackage
, если он еще не установлен в site-packages
? У меня была следующая идея, но она терпит неудачу, поскольку 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)