Posted at

__file__を使用しても実行中のスクリプトのディレクトリ名を取得できない理由を調べる


いきなり結論


Pythonの__file__は、対話モードで実行するとエラーになる


 参考:https://takeg.hatenadiary.jp/entry/2019/02/06/085241


きっかけ

↓↓の構文が何を表しているのかを知りたくてpython対話モード上で試したら

エラーを吐いて終了した。mnist.py上で実行したらうまくいったのに、、、なぜだろう…?

試行錯誤したらなんとなくうまくいったけど、何がどうおかしかったのか整理することにした。


実行に使用したプログラムの一部

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

save_file = dataset_dir + "/mnist.pkl"

ちなみ結論からいうと、python実行時の実行コンソールのカレントディレクトリ配下にある"mnist.pkl"をsave_fileに代入することを指す。

今回の場合、実行時は

/home/ec2-user/environment/deep-learning-from-scratch/dataset/mnist.py

から実行するので、そこと同じディレクトリにある

/home/ec2-user/environment/deep-learning-from-scratch/dataset/mnist.pkl

をsave_fileに代入することになる。


最終的にうまくいった構文

>>> print(os.path.dirname(os.path.abspath('__file__')))

/home/ec2-user/environment/deep-learning-from-scratch/ch01

これが基本、として以下の試行錯誤の歴史を振り返る。


で、ここからしくじりの記録を確認

cloud9の実行コンソール上で試行錯誤した結果が残っているのでこれを眺めていく。

何がおかしいのかなぁ…

>>> print(os.path.dirname(os.path.abspath(__file__)))

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'os' is not defined ←そもそもosモジュールをインポートしていない
>>> import os.path
>>> print(os.path.dirname(os.path.abspath(__file__))) ←よく見ると__file__をシングルクォート(')で囲んでない
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name '__file__' is not defined

ともかくどうやったらうまくいくのかを知りたくて調べたら↓↓にたどり着いた。

 https://qiita.com/opankopan/items/42a78754aa2fe6b6a29f

結果、なぜかうまくいった、って感じだった。まだピンと来ていない。

dir3はエラーがでているがsysモジュールをインポートしてないのが問題のようだ。今回は割愛。

>>> current_dir1 = os.path.dirname(os.path.abspath("__file__"))

>>>
>>> current_dir2 = os.path.dirname(os.path.abspath('__file__'))
>>>
>>> current_dir3 = os.path.dirname(os.path.abspath(sys.argv[0]))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'sys' is not defined
>>>
>>> print(current_dir1)
/home/ec2-user/environment/deep-learning-from-scratch/ch01
>>> print(current_dir2)
/home/ec2-user/environment/deep-learning-from-scratch/ch01
>>> print(current_dir3)print(os.path.dirname(os.path.abspath(__file__))) ←よくみるとprint(current_dir3)でいいのに余計なモノついてる
File "<stdin>", line 1
print(current_dir3)print(os.path.dirname(os.path.abspath(__file__)))
^
SyntaxError: invalid syntax

↑は変数に一度格納しているが

print()で囲めばいいよね?ってことでやってみたらうまくいった。

ちゃんとカレントディレクトリ出てる

>>> print(os.path.dirname(os.path.abspath('__file__')))

/home/ec2-user/environment/deep-learning-from-scratch/ch01
>>>


何が違ったのか?

違いは、シングルクォートで囲んだかどうか、の違いっぽい。

シングルクォートで囲む必要があるときとないときの違いってなんだろ?


成功したやつ

>>> print(os.path.dirname(os.path.abspath(__file__)))


失敗したやつ

>>> print(os.path.dirname(os.path.abspath('__file__')))

…出てきた!やっぱり同じことで悩んでる人がいるんだねぇ~よかった

https://takeg.hatenadiary.jp/entry/2019/02/06/085241

曰く、


Pythonの__file__は、対話モードで実行するとエラーになる


だそうだ。


まとめ

対話モードだと少し勝手が違うんだねぇ~

~めでたしめでたし~