__file__とは?Pythonでの使い方・意味・注意点を初心者向けに解説

Pythonを学習していると、__file__という記述を見かけることがあります。「__file__は何を表しているの?」「ファイルの場所を取得できるの?」「__file__が使えないのはなぜ?」と疑問に感じる方も多いでしょう。

この記事では、Pythonの__file__について、基本的な意味から実践的な使い方、os.pathpathlibとの組み合わせ、注意点まで初心者向けにわかりやすく解説します。

__file__とは?

__file__は、現在実行しているPythonファイルのパスを格納する特殊な変数です。

print(__file__)

例えば、次のようなPythonファイルがあるとします。

/home/user/project/main.py

main.pyに以下のコードを書きます。

print(__file__)

実行すると、環境によって次のように表示されます。

/home/user/project/main.py

つまり、__file__を使うと、実行中のPythonファイル自身の場所を確認できるわけです。

__file__はPythonの組み込み変数?

厳密には、__file__は一般的な組み込み関数や組み込み変数というより、Pythonがモジュールに設定する特殊な属性(グローバル変数)です。

Pythonには、__name____doc____package__など、__で囲まれた特殊な名前が存在します。

__file__もその一つです。

print(__name__)
print(__file__)

__file__でPythonファイルの場所を確認する

最も基本的な使い方は、print()で表示する方法です。

print(__file__)

例えば、Windowsでは次のように表示されることがあります。

C:\Users\user\project\main.py

macOSやLinuxでは、次のような形式になります。

/Users/user/project/main.py

OSによってパスの書き方は異なりますが、__file__を使えば実行中のPythonファイルの場所を取得できます。

__file__からファイル名だけを取得する

__file__にはファイル名まで含まれています。

例えば、

print(__file__)

の結果が、

/home/user/project/main.py

だったとします。

ここからファイル名だけを取り出したい場合は、pathlibを利用できます。

from pathlib import Path

filename = Path(__file__).name

print(filename)

実行結果:

main.py

このように、Path(__file__).nameでファイル名だけを取得できます。

__file__からディレクトリを取得する

Pythonファイルが保存されているディレクトリを取得することもできます。

from pathlib import Path

directory = Path(__file__).parent

print(directory)

例えば、次のような結果になります。

/home/user/project

__file__そのものは、

/home/user/project/main.py

ですが、.parentを使うことで親ディレクトリを取得できます。

__file__の絶対パスを取得する

__file__の値が相対パスになっている場合など、絶対パスとして扱いたい場合があります。

その場合はPath.resolve()を使えます。

from pathlib import Path

file_path = Path(__file__).resolve()

print(file_path)

例えば、次のような絶対パスを取得できます。

/Users/user/project/main.py

__file__とpathlibを組み合わせる

Pythonで__file__を利用する場合、pathlibと組み合わせる方法が便利です。

例えば、Pythonファイルと同じディレクトリにあるdata.txtを指定する場合、次のように書けます。

from pathlib import Path

base_dir = Path(__file__).resolve().parent
data_file = base_dir / "data.txt"

print(data_file)

ディレクトリ構造が次のようになっている場合を考えてみましょう。

project/
├── main.py
└── data.txt

次のコードによって、projectディレクトリを取得できます。

base_dir = Path(__file__).resolve().parent

そのうえで、

data_file = base_dir / "data.txt"

とすれば、data.txtへのパスを作れます。

__file__を使って画像ファイルを読み込む

__file__は、画像やCSV、JSONなどのファイルを読み込むときにも便利です。

例えば、次のような構成のプロジェクトがあるとします。

project/
├── main.py
└── images/
    └── sample.jpg

main.pyから画像ファイルのパスを作る場合は、次のように書けます。

from pathlib import Path

base_dir = Path(__file__).resolve().parent
image_path = base_dir / "images" / "sample.jpg"

print(image_path)

__file__を基準にすることで、Pythonファイルが存在する場所を基準として画像ファイルを指定できます。

__file__とカレントディレクトリの違い

初心者が特に混乱しやすいのが、__file__と「カレントディレクトリ」の違いです。

例えば、次のコードを実行します。

import os

print(__file__)
print(os.getcwd())

すると、異なるパスが表示されることがあります。

__file__

現在のPythonファイルの場所を表します。

os.getcwd()

現在の作業ディレクトリ(カレントディレクトリ)を表します。

例えば、次のような違いが発生する場合があります。

__file__
/home/user/project/main.py

os.getcwd()
/home/user

つまり、

  • __file__=Pythonファイルがある場所
  • os.getcwd()=プログラムを実行したときの作業場所

という違いがあります。

__file__とos.pathを使う方法

以前からPythonでは、os.pathを使ってファイルパスを操作する方法がよく使われてきました。

例えば、Pythonファイルがあるディレクトリを取得するなら、次のように書けます。

import os

base_dir = os.path.dirname(os.path.abspath(__file__))

print(base_dir)

これは現在でも利用できます。

ただし、新しいコードでは、

from pathlib import Path

base_dir = Path(__file__).resolve().parent

のようにpathlibを使うと、より読みやすくなります。

__file__と「相対パス」の問題

Pythonでファイルを扱うとき、次のようなコードを書くことがあります。

open("data.txt")

これはカレントディレクトリを基準にdata.txtを探します。

そのため、Pythonファイルとdata.txtが同じ場所にあっても、実行場所によってはファイルが見つからないことがあります。

そこで、__file__を基準にします。

from pathlib import Path

data_file = Path(__file__).resolve().parent / "data.txt"

with open(data_file, encoding="utf-8") as f:
    data = f.read()

こうすると、実行場所ではなくPythonファイルの場所を基準にファイルを指定できます。

__file__が使えない場合がある

便利な__file__ですが、常に利用できるわけではありません。

特に注意したいのが、Pythonの対話型環境です。

例えば、ターミナルで次のコマンドを実行してPythonインタプリタを起動します。

python

その後、

print(__file__)

とすると、

NameError: name '__file__' is not defined

となることがあります。

これは、実行しているコードが通常の.pyファイルではないためです。

Jupyter Notebookでは__file__が使えないことがある

Jupyter NotebookやJupyterLabなどでも、通常のPythonファイルとは実行環境が異なるため、

print(__file__)

が使えない場合があります。

同様に、

NameError: name '__file__' is not defined

というエラーになることがあります。

これは__file__の使い方が間違っているというより、そもそも__file__が定義される環境ではないことが原因です。

Google Colabでも__file__に注意

Google Colabなどのノートブック環境でも、通常の.pyファイルとは異なるため、__file__が利用できないケースがあります。

そのため、

from pathlib import Path

Path(__file__).resolve()

を実行してエラーになった場合は、コードを実行している環境が通常のPythonスクリプトなのかを確認することが重要です。

if __name__ == “__main__”との違い

Pythonでは、次のような記述もよく登場します。

if __name__ == "__main__":

__file__と似たような「特殊な名前」なので混同しやすいですが、役割は異なります。

__file__

Pythonファイルのパスを表します。

print(__file__)

__name__

現在のモジュール名を表します。

print(__name__)

そのため、

if __name__ == "__main__":
    print("直接実行されました")

と、

print(__file__)

は別の目的で使用します。

__file__を使った実践例

例えば、次のようなプロジェクトがあるとします。

myproject/
├── main.py
└── data/
    └── sample.txt

main.pyからsample.txtを読み込む場合は、次のように書けます。

from pathlib import Path

base_dir = Path(__file__).resolve().parent
file_path = base_dir / "data" / "sample.txt"

with open(file_path, encoding="utf-8") as f:
    text = f.read()

print(text)

この方法なら、プログラムをどのディレクトリから実行しても、Pythonファイルを基準としてsample.txtを探せます。

__file__を使うメリット

__file__を使う主なメリットは、Pythonファイル自身を基準にパスを組み立てられることです。

特に次のようなケースで便利です。

  • 設定ファイルを読み込む
  • CSVファイルを読み込む
  • JSONファイルを読み込む
  • 画像ファイルを読み込む
  • テンプレートファイルを読み込む
  • プロジェクト内のファイルを参照する

例えば、

from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent

としておけば、以降は、

BASE_DIR / "data" / "sample.csv"

のようにプロジェクト内のファイルを指定できます。

__file__を使うときの注意点

1. Jupyter Notebookなどでは使えないことがある

通常の.pyファイルでは利用できますが、Notebookや対話型インタプリタでは__file__が定義されていないことがあります。

2. __file__だけで絶対パスとは限らない

環境によっては__file__が相対パスになる場合があります。

確実に絶対パスとして扱いたい場合は、

Path(__file__).resolve()

とするとよいでしょう。

3. Pythonファイルの場所とカレントディレクトリは違う

__file__と、

os.getcwd()

は同じとは限りません。

ファイルの場所を基準にしたいのか、実行時の作業ディレクトリを基準にしたいのかを意識することが重要です。

よくある質問

__file__とは何ですか?

__file__は、現在実行しているPythonモジュールのファイルパスを表す特殊な変数です。

__file__でファイル名を取得できますか?

取得できます。

from pathlib import Path

print(Path(__file__).name)

とすると、ファイル名だけを取得できます。

__file__でフォルダを取得できますか?

取得できます。

from pathlib import Path

print(Path(__file__).resolve().parent)

とすると、Pythonファイルが存在するディレクトリを取得できます。

__file__がNameErrorになるのはなぜですか?

Jupyter Notebook、Pythonインタプリタ、Google Colabなど、通常のPythonスクリプトとは異なる環境では__file__が定義されていない場合があります。

__file__とos.getcwd()は何が違いますか?

__file__はPythonファイルの場所、os.getcwd()は現在の作業ディレクトリを表します。

両者は同じとは限りません。

まとめ

Pythonの__file__は、現在実行しているPythonファイルの場所を取得するときに便利な特殊な変数です。

基本的には、

print(__file__)

でファイルパスを確認できます。

ファイルの場所を基準に別のファイルを扱う場合は、pathlibと組み合わせて、

from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent

とする方法がおすすめです。

特に、CSV・JSON・画像・設定ファイルなどを読み込むプログラムでは、__file__を理解しておくと、「実行する場所によってファイルが見つからない」というトラブルを避けやすくなります。

Python初心者の方は、まず次のように覚えておくとよいでしょう。

__file__「今動かしているPythonファイル自身のパス」

プログラミング学習に興味がある方は、まずは無料体験会へ

無料体験会・お申し込みはこちら