Edited at

絶対パスの取得(まとめなおし)

More than 1 year has passed since last update.

この投稿は、以前書いた投稿に対しいくつかコメントを頂いたので、その情報を元に、少しまとめ直してみました。

間違いなどなりましたら、アドバイスお願いします。

以前の記事:絶対パスの取得「__file__」

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

環境

Ubuntu 16.04.5 LTS

Python 3.6.3 :: Anaconda, Inc.


1. 「__file__」「'__file__'」「"__file__"」の違いについて


1-1. ターミナルから「.py」ファイルを実行する場合


1-1-1. OKな書き方


sample1_OK.py

import os

print("os.path.dirname(os.path.abspath('__file__')): %r" % (os.path.dirname(os.path.abspath('__file__'))))
print("os.path.dirname(os.path.abspath(__file__)): %r" % (os.path.dirname(os.path.abspath(__file__))))



実行結果

os.path.dirname(os.path.abspath('__file__')): '/home/aa/bbb'

os.path.dirname(os.path.abspath(__file__)): '/home/aa/bbb'


1-1-2. NGな書き方


sample1_NG.py

print("os.path.dirname(os.path.abspath("__file__")): %r" % (os.path.dirname(os.path.abspath("__file__"))))



実行結果

SyntaxError: invalid syntax



1-2. jupyter noteboook上から「.ipynd」ファイルを実行する場合


1-2-1. OKな書き方


sample2_OK.py


import os

print("os.path.dirname(os.path.abspath('__file__')): %r" % (os.path.dirname(os.path.abspath('__file__'))))



実行結果

os.path.dirname(os.path.abspath('__file__')): '/home/aa/bbb'



1-1-2. NGな書き方


sample2_NG.py

print("os.path.dirname(os.path.abspath(__file__)): %r" % (os.path.dirname(os.path.abspath(__file__))))

print("os.path.dirname(os.path.abspath("__file__")): %r" % (os.path.dirname(os.path.abspath("__file__"))))


実行結果

SyntaxError: invalid syntax



1-1-3. NGな書き方を、こうするとOK


Sample3_OK.py

import os

dirname = os.path.dirname(os.path.abspath("__file__"))
print(dirname)



実行結果

'/home/aa/bbb'



1-3. 小括

「'__file__'」を使うと、ターミナルから実行しても、jupyter notebookから実行しても、事故が少なさそうです。


2.パスの取得


2-1. 絶対パスの取得


2-1-1. python3.4より前のバージョンでの書き方

ターミナルから実行しても、jupyter notebookで実行しても、このコードでOK。。


pathli_before34.py


import os

print("os.path.dirname(os.path.abspath('__file__')): %r" % (os.path.dirname(os.path.abspath('__file__'))))
print("os.path.dirname(os.path.abspath('__file__')): %s" % (os.path.dirname(os.path.abspath('__file__'))))



実行結果

os.path.dirname(os.path.abspath('__file__')): '/home/aa/bbb'

os.path.dirname(os.path.abspath('__file__')): /home/aa/bbb


2-1-1. python3.4以降のバージョンでの書き方

ターミナルから実行しても、jupyter notebookで実行しても、このコードでOK。


pathli_after34.py

from pathlib import Path

print("Path().resolve('__file__'): %r" % (Path().resolve('__file__')))
print("Path().resolve(): %r" % (Path().resolve()))
print("Path().resolve(): %s" % (Path().resolve()))



実行結果

Path().resolve('__file__'): PosixPath('/home/aa/bbb')

Path().resolve(): PosixPath('/home/aa/bbb')
Path().resolve(): /home/aa/bbb

##2-2. カレントパスの取得(Python3.4以降)

ターミナルから実行しても、jupyter notebookで実行しても、このコードでOK。


pathli_after34_c.py

print("Path().resolve('__file__'): %r" % (Path('__file__')))

print("Path().resolve(): %r" % (Path()))
print("Path().resolve(): %s" % (Path()))


実行結果

Path().resolve('__file__'): PosixPath('__file__')

Path().resolve(): PosixPath('.')
Path().resolve(): .


3. まとめ

個人的には、絶対PATHを取得するには、「pathlib」を使ったほうがわかりやすい。

Python2などで書かれた古いコードを写経する時のために、「os.path」の知識だけ持ってれば良いのかなと思えました。


4.余談

今回、pathlibモジュールをテストするにあたり、テスト用に自分で作成したコードのファイル名を「pathlib.py」としていました。

PYTHONPATHの問題だと思うのですが、モジュール名とテストコードファイル名が重複してしまったせいか、pathlibモジュールをimportすることができなくなり、原因を調べるのに苦労しました。

おかげで、色々勉強させて頂きました。(^_^;)

参考にさせて頂いたページ

https://www.sejuku.net/blog/54425

https://qiita.com/meznat/items/a1cc61edb1e340d0b1a2