Python: почему бы Python перестать сохранять в текущем рабочем каталоге
Всякий раз, когда я сохранял файл в Python, он сохранял в текущем рабочем каталоге. По какой-то неизвестной причине Python прекратил сохранение в pwd
, Мои цифры теперь сохраняются в каталоге под ним. Поэтому вместо сохранения в /Documents/.../OrbitalMechanics/OrbitalNotes
теперь они сохраняются в /Documents/.../OrbitalMechanics
, Моя операционная система - Ubuntu 13.04, я использую Emacs и пишу программу из терминала. Когда я звоню .py
файл, путь emacs ~/Documents/.../OrbitalMechanics/OrbitalNotes/stumpff.py
, Поэтому я в правильном каталоге.
Что может вызвать эту проблему? Я не изменил ничего, что обычно делаю, когда сохраняю фигуру.
Программа, где это произошло, находится ниже:
#!/usr/bin/env ipython
# This program plots the Stumpff functions C(z) and S(z)
import numpy as np
import pylab
from matplotlib.ticker import MaxNLocator
def C(z):
if z > 0:
return (1 - np.cos(z ** 0.5)) / z
elif z < 0:
return (np.cosh(np.sqrt(-z)) - 1) / -z
return 0.5
def S(z):
if z > 0:
return (np.sqrt(z) - np.sin(z ** 0.5)) / np.sqrt(z) ** 3
elif z < 0:
return (np.sinh(np.sqrt(-z)) - np.sqrt(-z)) / np.sqrt(-z) ** 3
return 1.0 / 6.0
vC = np.vectorize(C)
vS = np.vectorize(S)
z = np.linspace(-50.0, 500.0, 500000.0)
y = vC(z)
y2 = vS(z)
fig = pylab.figure()
ax = fig.add_subplot(111)
ax.plot(z, y, 'r')
ax.plot(z, y2, 'b')
pylab.legend(('$C(z)$', '$S(z)$'), loc = 0)
pylab.xlim((-50, 0))
pylab.ylim((0, 15))
pylab.xlabel('$z$')
pylab.gca().xaxis.set_major_locator(MaxNLocator(prune = 'lower'))
pylab.savefig('stumpffneg50to0.eps', format = 'eps')
Редактировать:
Ранее, когда я сохранял рисунок, рисунок сохранялся в каталоге, где .py
файл был найден, даже если я не был в этом каталоге. То есть я мог бы быть в домашнем каталоге, запустить файл в emacs
и файл будет там, где я хотел его сохранить. Теперь это не так, даже если файл всегда сохранялся в месте расположения скрипта Python.
Если я запускаю файл из терминала как ipython ~/path/to/file
цифры сохранят где .py
файл находится.
Если я открою файл в emacs
и использовать C-c C-c
чтобы запустить файл, файлы сохранятся на один уровень вниз от каталога .py
файл находится в.
Если я перейду в каталог, откройте файл в emacs
, файл снова сохранит один уровень вниз.
1 ответ
Когда вы запускаете Python, он наследует свой текущий рабочий каталог из оболочки. Так, например:
$ cd ~
$ ~/Documents/.../OrbitalMechanics/OrbitalNotes/stumpff.py
В этом случае текущий рабочий каталог ~
не ~/Documents/.../OrbitalMechanics/OrbitalNotes/
,
Это означает, что любые относительные пути относительно ~
, так что если вы просто создаете файл с именем foo.data
, это заканчивается как ~/foo.data
,
Итак, что, если вы хотите получить файлы в пути, такие как ~/Documents/.../OrbitalMechanics/OrbitalNotes/foo.data
? Есть два основных способа сделать это: либо установить для cwd путь к сценарию, либо явно использовать путь к сценарию. И есть два способа сделать первую часть, снаружи или внутри скрипта Python. И… ну, давайте просто рассмотрим все варианты по одному.
Если вы хотите запустить скрипт из собственного рабочего каталога, вы можете, конечно, вручную cd
сначала в этот каталог, или вы можете написать псевдоним bash или функцию или скрипт, который делает что-то вроде:
$(cd $(dirname $1) ./$(basename $1))
Очевидно, вам захочется немного поумнеть, если вы хотите передать несколько аргументов или если вы хотите использовать его в python ~/Documents/.../OrbitalMechanics/OrbitalNotes/stumpff.py
вместо просто ~/Documents/.../OrbitalMechanics/OrbitalNotes/stumpff.py
так что сценарий $2
и т. д. Но это все основные вещи.
Если вы хотите, чтобы скрипт изменил свой собственный рабочий каталог, вы можете сделать это в начале скрипта:
import os
import sys
scriptpath = os.path.dirname(__file__)
os.chdir(scriptpath)
(В некоторых случаях вы можете использовать sys.argv[1]
вместо __file__
, но детали трудно объяснить. Если вы хотите учиться, вы можете прочитать документы для каждого. Если вы не хотите учиться и столкнулись с проблемой, распечатайте __file__
и посмотрите, выглядит ли это правильно, и, если нет, попробуйте другой.)
Или вы можете просто явно использовать scriptpath
в качестве основы вместо использования cwd-относительных путей. В этом случае вы, вероятно, захотите использовать абсолютный путь к вашему сценарию в качестве основы (поэтому более поздние вызовы chdir
не повлияет на тебя)
import os
import sys
scriptpath = os.path.abspath(os.dirname(__file__))
# ...
datapath = os.path.join(scriptpath, 'foo.data')
with open(datapath, 'w') as datafile:
# ...