Pythonで実行中のファイルの場所(パス)を取得する__file__

Pythonで実行中のスクリプトファイルxxx.pyの場所(パス)を取得するには__file__を使います。実行中のファイルの場所を基準にほかのファイルを読み込んだりする場合に便利です。 __file__で得られるのはカレントディレクトリ(作業ディレクトリ)からの相対パス。標準ライブラリのosモジュールを使うと絶対パスを取得することもできます。 以下の内容について説明します。

os.getcwd()と__file__ 実行中のファイルのファイル名、ディレクトリ名を取得 実行中のファイルの絶対パスを取得 実行中のファイルの場所を基準にほかのファイルを読み込み カレントディレクトリを実行中のファイルのディレクトリに移動 実行時のカレントディレクトリに依存せず同じ処理が可能

カレントディレクトリ(作業ディレクトリ)の取得、変更については

なお、Jupyter Notebook(xxx.ipynb)では__file__は使えないので気をつけてください。

os.getcwd()と__file__

以下のディレクトリで作業するものとします。Windowsではpwdではなくdirコマンドでカレントディレクトリを確認できます。 pwd

/Users/mbp/Documents/my-project/python-snippets/notebook

下の階層(data/src)に以下の内容のPythonのスクリプトファイル(file_path.py)を作成。

import os

print('getcwd:      ', os.getcwd())
print('__file__:    ', __file__)

pythonコマンドで指定して実行します。

python3 data/src/file_path.py
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook
# __file__:     data/src/file_path.py

os.getcwd()でカレントディレクトリが、__file__で実行したスクリプトファイルのカレントディレクトリからの相対パスが取得できています。 以降の例では同じスクリプトファイル(file_path.py)に追記して、上記のディレクトリから実行するものとします。

実行中のファイルのファイル名、ディレクトリ名を取得

実行中のファイルのファイル名、ディレクトリ名を取得するには標準ライブラリのosモジュールの関数os.basename(), os.dirname()を使います。

print('basename:    ', os.path.basename(__file__))
print('dirname:     ', os.path.dirname(__file__))

実行結果。

# basename:     file_path.py
# dirname:      data/src

osモジュールの関数os.basename(), os.dirname()などについての詳細は

実行中のファイルの絶対パスを取得

__file__で取得できるのはカレントディレクトリからの相対パスだが、os.abspath()で絶対パスに変換できます。ディレクトリも絶対パスで取得できます。

print('abspath:     ', os.path.abspath(__file__))
print('abs dirname: ', os.path.dirname(os.path.abspath(__file__)))

実行結果。

# abspath:      /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# abs dirname:  /Users/mbp/Documents/my-project/python-snippets/notebook/data/src

実行中のファイルの場所を基準にほかのファイルを読み込み

実行中のファイルの場所(パス)を基準にほかのファイルを読み込みたい場合は、実行中のファイルのディレクトリと読み込みたいファイルの実行中のファイルからの相対パスをos.path.join()で連結します。 実行中のファイルと同じディレクトリのファイルを読み込む場合はファイル名のみを指定すれば問題ありません。

print('[set target path 1]')
target_path_1 = os.path.join(os.path.dirname(__file__), 'test.txt')

print('target_path_1: ', target_path_1)

print('read target file:')
with open(target_path_1) as f:
    print(f.read())

実行結果。

# [set target path 1]
# target_path_1:  data/src/test.txt
# read target file:
# line 1
# line 2
# line 3

上の階層は../で表す。

print('[set target path 2]')
target_path_2 = os.path.join(os.path.dirname(__file__), '../dst/test_new.json')

print('target_path_2: ', target_path_2)

print('read target file:')
with open(target_path_2) as f:
    print(f.read())

実行結果。

# [set target path 2]
# target_path_2:  data/src/../dst/test_new.json
# read target file:
# {
#   "A": 100,
#   "B": "abc",
#   "C": "あいうえお"
# }

ファイルの読み込みについては

カレントディレクトリを実行中のファイルのディレクトリに移動

スクリプト内でカレントディレクトリを実行中のファイルのディレクトリに移動する場合はos.chdir()を使います。

os.getcwd()で移動していることが確認できます。

print('[change directory]')
os.chdir(os.path.dirname(os.path.abspath(__file__)))
print('getcwd:      ', os.getcwd())

実行結果。

# [change directory]
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook/data/src

カレントディレクトリを移動すれば、ファイルを読み込む場合に実行中のファイルのディレクトリと連結する必要はない。実行中のファイルからの相対パスを指定すれば問題ありません。

print('[set target path 1 (after chdir)]')
target_path_1 = 'test.txt'

print('target_path_1: ', target_path_1)

print('read target file:')
with open(target_path_1) as f:
    print(f.read())

print()
print('[set target path 2 (after chdir)]')
target_path_2 = '../dst/test_new.json'

print('target_path_2: ', target_path_2)

print('read target file:')
with open(target_path_2) as f:
    print(f.read())

実行結果。

# [set target path 1 (after chdir)]
# target_path_1:  test.txt
# read target file:
# line 1
# line 2
# line 3
#
# [set target path 2 (after chdir)]
# target_path_2:  ../dst/test_new.json
# read target file:
# {
#   "A": 100,
#   "B": "abc",
#   "C": "あいうえお"
# }

実行時のカレントディレクトリに依存せず同じ処理が可能

__file__を使って実行中のファイルパスを取得すると、実行時のカレントディレクトリに依存せず同じ処理を行うことができます。 これまでの例の結果をまとめて示す。

pwd
# /Users/mbp/Documents/my-project/python-snippets/notebook

python3 data/src/file_path.py
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook
# __file__:     data/src/file_path.py
# basename:     file_path.py
# dirname:      data/src
# abspath:      /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# abs dirname:  /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
#
# [set target path 1]
# target_path_1:  data/src/test.txt
# read target file:
# line 1
# line 2
# line 3
#
# [set target path 2]
# target_path_2:  data/src/../dst/test_new.json
# read target file:
# {
#   "A": 100,
#   "B": "abc",
#   "C": "あいうえお"
# }
#
# [change directory]
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
#
# [set target path 1 (after chdir)]
# target_path_1:  test.txt
# read target file:
# line 1
# line 2
# line 3
#
# [set target path 2 (after chdir)]
# target_path_2:  ../dst/test_new.json
# read target file:
# {
#   "A": 100,
#   "B": "abc",
#   "C": "あいうえお"
# }

ターミナルでカレントディレクトリを移動して同じスクリプトファイルを実行。異なる場所から実行しても同じファイルを読み出せているのが確認できます。

cd data/src

python3 file_path.py
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# __file__:     file_path.py
# basename:     file_path.py
# dirname:      
# abspath:      /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# abs dirname:  /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
#
# [set target path 1]
# target_path_1:  test.txt
# read target file:
# line 1
# line 2
# line 3
#
# [set target path 2]
# target_path_2:  ../dst/test_new.json
# read target file:
# {
#   "A": 100,
#   "B": "abc",
#   "C": "あいうえお"
# }
#
# [change directory]
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
#
# [set target path 1 (after chdir)]
# target_path_1:  test.txt
# read target file:
# line 1
# line 2
# line 3
#
# [set target path 2 (after chdir)]
# target_path_2:  ../dst/test_new.json
# read target file:
# {
#   "A": 100,
#   "B": "abc",
#   "C": "あいうえお"
# }
Last Updated: 6/26/2019, 10:34:03 PM