Определение текущей директории скрипта в Python: лучшие методы

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Чтобы определить директорию текущего скрипта, используйте __file__ вместе с os.path.abspath:

Python
Скопировать код
import os

# Где мы находимся? Это путь к исполняемому скрипту, `__file__`!
script_dir = os.path.abspath(os.path.dirname(__file__))
print(script_dir)
Кинга Идем в IT: пошаговый план для смены профессии

Решения при отсутствии __file__

Иногда переменная __file__ может быть недоступна, например, при запуске скрипта через exec или execfile. В таком режиме для обеспечения видимости __file__ необходимо включить её в глобальный контекст:

Python
Скопировать код
# Помним о необходимости передать `__file__` в exec!
# Забыть об этом – значит столкнуться с ошибкой.
globals_dict = globals()
globals_dict["__file__"] = __file__
exec(open("your_script.py").read(), globals_dict)

Работа с символическими ссылками и скомпилированными программами

Для определения реального пути файла, который скрыт за символической ссылкой, используйте функцию os.path.realpath. Она позволяет проити по ссылке и увидеть, где находится исходный файл:

Python
Скопировать код
# Время вскрыть истинное местоположение файла.
realpath = os.path.realpath(__file__)
print(realpath)

Для использования скриптов, запакованных в исполняемый файл или приложение-архив, реальный путь можно получить с помощью модуля sys:

Python
Скопировать код
import sys

# Это полезно применять в случае работы с PyInstaller или подобной ситуацией.
if getattr(sys, 'frozen', False):
    bundle_dir = sys._MEIPASS  # Благодарим PyInstaller за этот хитрый трюк
else:
    bundle_dir = os.path.dirname(os.path.abspath(__file__))

Особенности применения в различных контекстах

Применение __file__ в интерактивном режиме и при работе с пакетами

Интерактивный режим не предусматривает использование __file__. Также могут возникнуть сложности при работе с импортируемыми пакетами. В этих случаях на помощь придет модуль inspect:

Python
Скопировать код
import inspect

# Давайте попробуем разобраться в текущем контексте. 🕵️‍♀️
filename = inspect.getframeinfo(inspect.currentframe()).filename
script_dir = os.path.dirname(os.path.abspath(filename))

Элегантное решение с применением pathlib

Модуль pathlib предлагает современное решение для работы с файловыми путями. С помощью метода resolve() ваш код станет более изящным и надежным:

Python
Скопировать код
from pathlib import Path

# Pathlib – элегантная и понятная работа с файловыми путями!
script_dir = str(Path(__file__).resolve().parent)

Рекомендации

Вот несколько советов для эффективной работы с файловыми путями:

  • Проверяйте контекст выполнения скрипта: разный путь будет получен при запуске скрипта, импорте как модуля или в случае запуска скомпилированного приложения.
  • Во время разработки программы и при переходе к скомпилированному варианту адаптируйте способы извлечения путей так, чтобы они были надежными в различных средах.
  • При использовании альтернативных реализаций Python следите за их совместимостью.
  • Используйте pathlib для усовершенствованного объектно-ориентированного доступа к файловой системе, упростите и улучшите ваш код.

Визуализация

Представьте взаимодействие с Python во время определения расположения вашего скрипта:

Markdown
Скопировать код
Ваш скрипт: "Где я нахожусь?"
Файловая система: "Позволь мне указать тебе путь."

import os
script_path = os.path.dirname(os.path.abspath(__file__))

print(script_path)

📍 '/path/to/your/script_directory'

Полезные материалы

  1. os.path — методы для работы с путями (Официальная документация Python)
  2. Что такое переменная __file__ в Python? (Обсуждение на Stack Overflow)
  3. Работа с модулем os в Python (Python Module of the Week представляет предельно ясный обзор модуля os)
  4. Обработка файловой системы Python с помощью pathlib (Детальная статья от Real Python)
  5. Как определить текущую директорию в Python (Обсуждение на Stack Overflow)
  6. Объектно-ориентированные пути файловой системы с помощью pathlib (Официальная документация pathlib)
  7. sys.argv и прочие возможности модуля sys (Полная документация Python для модуля sys)