Что именно представляет собой текущий рабочий каталог?
В моей книге говорится:
Каждая программа, запущенная на вашем компьютере, имеет текущий рабочий каталог, или cwd. Предполагается, что любые имена файлов или пути, которые не начинаются с корневой папки, находятся в текущем рабочем каталоге
Поскольку я использую OSX, моей корневой папкой является / . Когда я набираю os.getcwd()
в моей оболочке Python, я получаю /Users/apple/Documents
. Почему я получаю папку Documents в моем cwd? Это говорит о том, что Python использует папку Documents? Нет ли какого-либо пути, ведущего к Python, который начинается с /
(корневая папка)? Кроме того, у каждой программы свой cwd?
Переведено автоматически
Ответ 1
У каждого процесса есть текущий каталог. Когда процесс запускается, он просто наследует текущий каталог от своего родительского процесса; и он, например, не устанавливается в каталог, содержащий программу, которую вы запускаете.
Для более подробного объяснения читайте дальше.
Когда диски стали достаточно большими, чтобы не хотелось, чтобы все ваши файлы находились в одном месте, производители операционных систем придумали способ структурирования файлов в каталогах. Таким образом, вместо сохранения всего в одном каталоге (или "папке", как теперь учат называть это новичков) вы могли бы создавать новые коллекции и другие новые коллекции внутри них (за исключением некоторых ранних реализаций, каталоги не могли содержать другие каталоги!)
По сути, каталог - это просто файл особого типа, содержимое которого представляет собой набор других файлов, которые также могут включать другие каталоги.
В примитивной операционной системе на этом история заканчивалась. Если бы вы хотели распечатать файл с именем, term_paper.txt
который находился в каталоге, spring_semester
который, в свою очередь, находился в каталоге, 2021
который находился в каталоге, studies
в каталоге mine
вам пришлось бы сказать
print mine/studies/2021/spring_semester/term_paper.txt
(за исключением того, что команда, вероятно, была чем-то более загадочным, чем print
, а разделителем каталогов могло быть что-то сумасшедшее, например квадратные скобки и двоеточия, или что-то в этом роде;
lpr [mine:studies:2021:spring_semester]term_paper.txt
но это неважно для данного изложения) и если бы вы захотели скопировать файл, вам пришлось бы произнести всю энчиладу дважды:
copy mine/studies/2021/spring_semester/term_paper.txt mine/studies/2021/spring_semester/term_paper.backup
Затем появилась концепция текущего рабочего каталога. Что, если бы вы могли сказать: "с этого момента, пока я не скажу иначе, все файлы, о которых я говорю, будут находиться в этом конкретном каталоге". Так родилась команда cd
(за исключением старых систем, таких как виртуальные машины, она называлась как-то более неуклюже, например SET DEFAULT
).
cd mine/studies/2021/spring_semester
print term_paper.txt
copy term_paper.txt term_paper.backup
На самом деле это все, что нужно. Когда вы cd
(или, в Python, os.chdir()
) меняете свой текущий рабочий каталог. Он остается до тех пор, пока вы не выйдете из системы (или иным образом не завершите этот процесс), или пока вы не cd
перейдете в другой рабочий каталог, или не переключитесь на другой процесс или окно, где вы запускаете отдельную команду, которая имеет свой собственный текущий рабочий каталог. Точно так же, как вы можете открыть свой файловый браузер (Explorer, или Finder, или Nautilus, или как там он называется) с несколькими окнами в разных каталогах, у вас может быть открыто несколько терминалов, и каждый из них запускает оболочку, которая имеет свой собственный независимый текущий рабочий каталог.
Итак, когда вы вводите pwd
в терминал (или cwd
или какую бы команду ни вызывали на вашем командном языке), результат будет в значительной степени зависеть от того, что вы делали в этом окне или процессе раньше, и, вероятно, зависит от того, как вы создали это окно или процесс. Во многих Unix-подобных системах, когда вы создаете новое окно терминала с соответствующим процессом оболочки, оно изначально открывается в вашем домашнем каталоге (/home/you
во многих системах Unix, /Users/you
на Mac, что-то более или менее похожее C:\Users\you
на последних версиях Windows), хотя, вероятно, ваш терминал может быть настроен на открытие где-то еще (обычно Desktop
или Documents
внутри вашего домашнего каталога в некоторых якобы "современных" и "дружественных" системах).
У многих новичков есть расплывчатая и неполная ментальная модель того, что происходит при запуске программы. Многие будут постоянно cd
заходить в любой каталог, содержащий их скрипт или программу, и будут искренне напуганы и сбиты с толку, когда вы скажете им, что вам это не обязательно. Если frobozz
находится в /home/you/bin
, то вам не нужно
cd /home/you/bin
./frobozz
потому что вы можете просто запустить его напрямую с помощью
/home/you/bin/frobozz
и аналогично, если ls
находится в /bin
, вы определенно этого не делаете
cd /bin
./ls
просто чтобы получить список каталогов.
Кроме того, как в ls
(или в Windows, dir
) пример должен легко убедить вас, любая программа, которую вы запускаете, будет искать файлы в вашем текущем каталоге. Не тот каталог, в котором была сохранена программа или скрипт. Потому что, если бы это было так, ls
можно было бы создать список каталога, в котором он находится (/bin
) - нет ничего особенного в программе составления списка каталогов, или программе копирования, или программе текстового процессора; все они по замыслу выглядят в текущем рабочем каталоге (хотя, опять же, некоторые программы с графическим интерфейсом будут запускаться, например, с вашего Documents
каталога в качестве текущего рабочего каталога, по замыслу, по крайней мере, если вы не скажете им иначе).
Многие новички пишут скрипты, которые требуют, чтобы входные и выходные файлы находились в определенном каталоге внутри домашнего каталога конкретного пользователя, но это просто плохой дизайн; хорошо написанная программа просто ищет в текущем рабочем каталоге свои входные файлы, если не указано иное, и записывает выходные данные в текущий каталог (или, возможно, создает новый каталог в текущем каталоге для своих выходных данных, если он состоит из нескольких файлов).
Таким образом, Python ничем не отличается от любых других программ. Если ваш текущий рабочий каталог является таким, /Users/you/Documents
когда вы запускаете python
, то этот каталог будет создаваться os.getcwd()
внутри вашего скрипта или интерпретатора Python (если вы не подключаетесь отдельно os.chdir()
к другому каталогу во время выполнения; но опять же, это, вероятно, не нужно, и часто это признак того, что скрипт был написан новичком). И если ваш скрипт Python принимает параметр имени файла, он, вероятно, должен просто передать операционной системе open
все, что передал пользователь, что означает, что относительные имена файлов относятся к текущему рабочему каталогу вызывающего пользователя.
python /home/you/bin/script.py file.txt
должно просто open(sys.argv[1])
и завершиться ошибкой, если file.txt
не существует в текущем каталоге. Давайте повторим это еще раз; он не ищет в /home/you/bin
для file.txt
- если, конечно, это также текущий рабочий каталог вас, вызывающего пользователя, в этом случае, конечно, вы могли бы просто написать
python script.py file.txt
Кстати, многие новички без необходимости пробуют что-то вроде
with open(os.path.join(os.getcwd(), "input.txt")) as data:
...
который вызывает без необходимости os.getcwd()
. Почему это ненужно? Если вы внимательно следили, то уже знаете ответ: операционная система в любом случае будет искать относительные имена файлов (например, здесь, input.txt
) в текущем рабочем каталоге. Итак, все, что вам нужно, это
with open("input.txt") as data:
...
Последнее замечание. В Unix-подобных системах все файлы в конечном итоге находятся внутри корневого каталога, /
который содержит ряд других каталогов (и обычно обычным пользователям не разрешается ничего туда записывать, а системные администраторы, имеющие право делать это, обычно не хотят). Каждое относительное имя файла можно превратить в абсолютное имя файла, проследив путь от корневого каталога до текущего каталога. Итак, если файл, к которому мы хотим получить доступ, находится в /home/you/Documents/file.txt
это означает, что home
находится в корневом каталоге и содержит you
, который содержит Documents
, который содержит file.txt
. Если бы ваш текущий рабочий каталог был /home
, вы могли бы ссылаться на тот же файл по относительному пути you/Documents/file.txt
; и если бы ваш текущий каталог был /home/you
, относительный путь к нему был бы Documents/file.txt
(и если бы ваш текущий каталог был /home/you/Music
, вы могли бы сказать ../Documents/file.txt
, но давайте не будем сейчас рассматривать этот пример дальше).
Windows имеет несколько иную структуру, с несколькими дисками с однобуквенными идентификаторами, каждый со своим собственным корневым каталогом; таким образом, корень диска C: - это C:\
, а корень диска D: - это D:\
и т.д. (а разделителем каталогов является обратная косая черта вместо косой черты, хотя вы можете использовать косую черту практически везде, что часто является хорошей идеей для сохранения вашего здравомыслия).
Ответ 2
Местоположение вашего интерпретатора python зависит от того, как вы его запустили, а также от последующих действий, предпринятых после его запуска, таких как использование модуля операционной системы для навигации по вашей файловой системе. Простой запуск интерпретатора поместит вас в каталог вашей установки python (не одинаковый в разных операционных системах). С другой стороны, если вы начнете с редактирования или запуска файла в определенном каталоге, вашим местоположением будет папка файла, который вы редактировали. Если вам нужно запустить интерпретатор в определенном каталоге и вы используете, например, idle, проще всего начать с создания там файла python тем или иным способом, и когда вы отредактируете его, вы можете запустить оболочку с помощью команды Run > Python Shell, которая уже будет в этом каталоге. Если вы используете интерпретатор командной строки, перейдите в папку, в которой вы хотите запустить свой интерпретатор, прежде чем запускать команду python / python3 / py. Если вам нужно выполнить навигацию вручную, вы, конечно, можете использовать следующее, о котором уже упоминалось:
import os
os.chdir('full_path_to_your_directory')
Ответ 3
Это не имеет ничего общего, в частности, с osx, это скорее концепция, общая для всех систем на базе unix, и, я полагаю, Windows тоже. os.getcwd()
является эквивалентом команды bash pwd
- она просто возвращает полный путь к текущему местоположению, в котором вы находитесь. Другими словами:
alex@suse:~> cd /
alex@suse:/> python
Python 2.7.12 (default, Jul 01 2016, 15:34:22) [GCC] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.getcwd()
'/'
Это зависит от того, где вы запустили оболочку / скрипт python.
Ответ 4
Обычно Python (за исключением случаев, когда вы работаете с виртуальными средами) доступен из любого вашего каталога. Вы можете проверить переменные в вашем path, и Python должен быть доступен. Таким образом, при запросе Python вы получаете каталог, в котором вы запустили Python. Измените каталог в вашей оболочке перед запуском Python, и вы увидите, что полученный результат изменится соответствующим образом.