Как правильно определить текущий каталог скриптов? - PullRequest
212 голосов
/ 15 сентября 2010

Хотелось бы узнать, как лучше определить текущий каталог скриптов в python?

Я обнаружил, что из-за множества способов вызова кода на Python трудно найти хорошее решение.

Вот некоторые проблемы:

  • __file__ не определено, если скрипт выполняется с exec, execfile
  • __module__ определяется только в модулях

Варианты использования:

  • ./myfile.py
  • python myfile.py
  • ./somedir/myfile.py
  • python somedir/myfile.py
  • execfile('myfile.py') (из другого сценария, который может находиться в другом каталоге и может иметь другой текущий каталог.

Я знаю, что не существует идеального решения, но я ищу лучший подход, который решает большинство случаев.

Наиболее часто используемый подход - os.path.dirname(os.path.abspath(__file__)), но он действительно не работает, если вы запускаете скрипт из другого с exec().

Внимание

Любое решение, использующее текущий каталог, завершится неудачей, оно может отличаться в зависимости от способа вызова скрипта или может быть изменено внутри запущенного скрипта.

Ответы [ 13 ]

2 голосов
/ 22 ноября 2011

Вот частичное решение, все еще лучшее, чем все опубликованные.

import sys, os, os.path, inspect

#os.chdir("..")

if '__file__' not in locals():
    __file__ = inspect.getframeinfo(inspect.currentframe())[0]

print os.path.dirname(os.path.abspath(__file__))

Теперь это работает для всех вызовов, но если кто-то использует chdir() для изменения текущего каталога, это также не удастся.

Примечания:

  • sys.argv[0] не будет работать, вернет -c, если вы выполните скрипт с python -c "execfile('path-tester.py')"
  • Я опубликовал полный тест на https://gist.github.com/1385555, и вы можете его улучшить.
1 голос
/ 24 марта 2017

Надеюсь, это поможет: - Если вы запустите скрипт / модуль из любого места, вы сможете получить доступ к переменной __file__, которая является модульной переменной, представляющей местоположение скрипта.

С другой стороны, если вы используете интерпретатор, у вас нет доступа к этой переменной, где вы получите имя NameError и os.getcwd() даст вам неправильный каталог, если вызапускаешь файл откуда-то еще.

Это решение должно дать вам то, что вы ищете во всех случаях:

from inspect import getsourcefile
from os.path import abspath
abspath(getsourcefile(lambda:0))

Я не проверил его полностью, но он решил мою проблему.

0 голосов
/ 12 сентября 2018

просто pwd
на ноутбуке jupyter: pwd + shift + enter
у шпиона: pwd + F9

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...