Разница между os.getcwd() и os.path.dirname(__file__)

В предыдущем проекте я использовал первую версию следующих двух строк. Теперь, когда я нашел getcwd(), я подумал, что это будет более короткая альтернатива.

print(os.path.dirname(__file__))  # D:/Personal_Software/my_project
print(os.getcwd())  # D:\Personal_Software\my_project

Я уже прочитал этот пост, но мне любопытно, как использовать «/» вместо «\». Я использую Windows 10, если это актуально.

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

Marcin Orlowski 26.12.2020 05:19
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
8
1
3 243
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Разница есть, хотя по одному сценарию ее не скажешь.

__file__ — это полное имя файла загруженного модуля или скрипта, поэтому получение его родительского каталога с помощью os.path.dirname(__file__) дает вам каталог, в котором находится скрипт.

Примечание: в Linux (и подобных ОС) такое имя файла может быть символической ссылкой на фактический файл, который может находиться где-то еще. Вы можете использовать os.path.realpath() для разрешения любых таких ссылок, если это необходимо, хотя обычно вы можете использовать эквивалентную символическую ссылку. В Windows они менее распространены, но вы также можете разрешать символические ссылки через realpath().

os.getcwd() получает текущий рабочий каталог. Если вы запускаете скрипт из каталога, в котором находится скрипт (что является распространенным), рабочий каталог будет таким же, как результат вызова из os.path.dirname(__file__).

Но если вы запускаете скрипт из другого каталога (например, python d:\some\path\script.py) или если вы меняете рабочий каталог во время скрипта (например, с помощью os.chdir()), текущий рабочий каталог изменился, а часть имени файла скрипта — нет.

Итак, это зависит от того, что вам нужно:

  • Нужен каталог, в котором находится ваш файл сценария? Используйте os.path.dirname(__file__)
  • Нужен каталог, в котором сейчас работает ваш скрипт? использовать os.getcwd()

Вы увидите / в одних результатах и ​​\ в других. К сожалению, MS Windows использует \ для разделения частей пути (например, C:\Program Files\App\), в то время как почти все другие операционные системы используют / (например, /home/user/script.py)

Python часто конвертирует их автоматически, поэтому вы можете использовать такие пути, как C:/Program Files/App, в Python и в Windows, но, как правило, лучше быть в безопасности и использовать os.path.sep.

Примечание: если вы используете Python 3, вам может быть лучше просто использовать pathlibPath вместо os.path. Он автоматически разрешает символические ссылки (хотя вы все равно можете разрешать ссылку, если хотите), а также имеет другие приятные удобства.

@ikegami, можешь привести пример? Вы имеете в виду ярлык Windows для скрипта Python и запускаете его с помощью pylauncher? Или вы имеете в виду ярлык для исполняемого файла Python со сценарием в качестве параметра?

Grismar 26.12.2020 05:57

Насколько я знаю, символическая ссылка также разрешается в файл для Python, поэтому с точки зрения скрипта нет разницы, использует ли он символическую ссылку или местоположение файла, в котором файл был первоначально создан? (хотя, конечно, есть разница между символической ссылкой и жесткой ссылкой) Но, похоже, вы говорите, что когда скрипт запускается по своей символической ссылке, это путь, который вы увидите в __file__, а не путь оригинала?

Grismar 26.12.2020 06:06
  • __file__ — это имя файла, предоставленное Python, точно так же, как оно было предоставлено.
  • os.path.dirname(__file__) обычно это каталог, в котором находится скрипт. (Но не всегда, как вы увидите ниже.)
  • os.path.dirname(os.path.realpath(__file__)) — это каталог, в котором находится скрипт.
  • os.getcwd() — текущий каталог.

Текущий каталог не имеет ничего общего с тем, где находится скрипт. Это путь для каждого процесса, используемый для разрешения относительных путей.

/tmp/ikegami/a.py:

#!/usr/bin/python3

import os

print(__file__)
print(os.path.dirname(__file__))
print(os.path.dirname(os.path.realpath(__file__)))
print(os.getcwd())
[~]$ bin/a                # A symlink to /tmp/ikegami/a.py
bin/a                     # The path provided to python3.
bin                       # NOT the directory in which the script is located.
/tmp/ikegami              # The directory in which the script is located.
/home/ikegami             # The current directory (~ = /home/ikegami)

[~]$ /tmp/ikegami/a.py
/tmp/ikegami/a.py         # The path provided to python3.
/tmp/ikegami              # The parent of the path provided to python3.
/tmp/ikegami              # The directory in which the script is located.
/home/ikegami             # The current directory (~ = /home/ikegami)

[~]$ cd /tmp/ikegami

[/tmp/ikegami]$ ./a.py
./a.py                    # The path provided to python3.
.                         # The parent of the path provided to python3.
/tmp/ikegami              # The directory in which the script is located.
/tmp/ikegami              # The current directory

(Эти тесты выполнялись на компьютере с Linux, потому что на этом компьютере с Windows у меня не установлен Python. Вы получите аналогичные результаты в Windows.)


меня интересует использование "/" против "\".

Windows всегда принимала как \, так и / в качестве разделителя каталогов.[1][2], как и DOS до этого.[3] Они эквивалентны. \ — это канонический разделитель (тот, который предпочтительнее для согласованности), но / работает так же хорошо.

Похоже, что ваша программа была запущена с помощью python3 D:/Personal_Software/my_project/file.py. __file__ содержит точный путь, предоставленный Python, а dirname(__file__) просто удаляет последний бит.

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


  1. Вы даже можете использовать // для путей UNC (//server/share) и подобных (//?/..., //./... и т. д.).

  2. Вопреки сделанным утверждениям, это относится к системным вызовам (т. случай для Power Shell (например, dir "c:/bin", c:/bin/myprog), и это случай в консоли Windows (например, c:/bin/myprog).

    Предупреждение: некоторые конкретные консольные команды Windows (например, dir) требуют, чтобы пути с / были в кавычках (например, dir "c:/"), потому что / сигнализирует им о начале опции.

  3. Ну, так как каталоги были введены в DOS 2.0.

Другие вопросы по теме