Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

いきなり結論

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__は、対話モードで実行するとエラーになる

だそうだ。

まとめ

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

~めでたしめでたし~

watyanabe164
会社ではインフラエンジニアやってます。一方プライベートではAIの可能性に感化されて趣味でpythonでAI関連のプログラムを試したり、そのほか興味の赴くままに様々な技術を試して楽しんでます。シンギュラリティが楽しみで仕方ない。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away