2016-06-02 5 views
3

Для того, чтобы установить некоторые пути для доступа к поддиректории моего приложения (как locale/), я использую это в settings.py:Как правильно настроить путь относительно запуска скрипта и в тестах?

__process_name = os.path.basename(sys.argv[0]) 
__abspath = os.path.abspath(sys.argv[0]) 
__l1 = len(__process_name) 
__l2 = len(__abspath) 
rootdir = __abspath[:__l2-__l1] 

И тогда, например, чтобы получить доступ к data/:

datadir = rootdir + "data/" 

проблемы когда я запускаю этот settings.py, когда я запускаю тесты (например, python3 -m py.test), то sys.argv[0] больше не соответствует myapp, и скрипт тестов не может получить доступ к data/.

Интересно, как бороться с этим, например:

  • Есть ли способ, чтобы получить тот же ROOTDIR от обоих моего приложения и набора тестов?
  • Или, должен ли я хранить settings.py только для моего приложения и предоставить набор тестов с правильным (жестко запрограммированным) rootdir?
  • Или укажите installdir в файле конфигурации, который будет установлен во время установки, а затем использован как моим приложением (вместо фрагмента выше), так и его набором тестов?
  • Я также подумал о замене sys.argv[0] на 'myappname', но, поскольку существуют разные каталоги с тем же именем, он не уверен, что получил правильный. (Кроме того, что, если в другом месте есть одна установленная версия и одна версия dev: как сделать различие между ними?)

Итак, какой был бы лучший способ справиться с этим?

+2

Вы пытались использовать 'os.path.dirname (os.path.abspath (__ file __))'? –

+0

@ TheCompiler Нет, не пробовал. Мне придется немного взломать его, чтобы справиться с разницей в уровне каталогов, но это определенно решило случай элегантно! Это умно! Вы можете добавить это как ответ. – zezollo

ответ

5

Итак, обычная вещь os.path.dirname(os.path.abspath(__file__)).

__file__ - это путь к текущему модулю, os.path.abspath гарантирует, что он является абсолютным, и os.path.dirname предоставляет вам часть каталога.

Если у вас есть модуль как часть пакета и необходимо, например, каталог в пакете, вы можете либо использовать os.path.join(..., os.pardir) в зависимости от ситуации, либо, если возможно, импортировать пакет (то есть его __init__.py) и сделать your_package.__file__.

Альтернативой, которую вы, возможно, захотите рассмотреть, также является указание ваших данных как данных пакета с помощью setuptools, а затем с помощью API pkg_resources для доступа к нему.