結論
デコレータを使い元のカレントディレクトリをセットし直す!
背景
Pythonでファイル処理をしていると、関数内でディレクトリ移動したくなる時があると思います。
しかし、関数内でos.chdir
を使うと、スコープを抜けてもカレントディレクトリは戻りません。
sample.py
import os
def move_dir():
os.chdir('fuga')
print(os.getcwd())
if __name__ == '__main__':
print(os.getcwd())
move_dir()
print(os.getcwd())
結果
.../hoge
.../hoge/fuga
.../hoge/fuga
カレントディレクトリを戻すためには、関数内で最初にカレントディレクトリを変数に保持し、
最後にもう一度元のディレクトリに移動する必要があります。
def move_dir():
dir = os.getcwd()
os.chdir('fuga')
print(os.getcwd())
os.chdir(dir)
ちょっと見栄えが悪いですね…
そうだ デコレータ、使おう
「前後に決まった処理をする」と言えばデコレータです。
という訳で、最後にカレントディレクトリを元に戻すデコレータを作りました。
以下のlocal_chdir
を使えばディレクトリ移動を(実質)ローカルにできます。
local_chdir.py
import os
def local_chdir(func):
def _inner(*args, **kwargs):
# 元のカレントディレクトリを変数に代入
dir_original = os.getcwd()
# 渡された関数実行
ret = func(*args, **kwargs)
# カレントディレクトリを元に戻す
os.chdir(dir_original)
return ret
return _inner
@local_chdir # デコレータ
def move_dir():
os.chdir('fuga')
print(os.getcwd())
if __name__ == '__main__':
print(os.getcwd())
move_dir()
print(os.getcwd())
結果
.../hoge
.../hoge/fuga
.../hoge
これで、関数内のディレクトリ移動を気にする必要がなくなりました!