LoginSignup
16
32

More than 5 years have passed since last update.

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

Last updated at Posted at 2018-09-08

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

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

以前の記事:絶対パスの取得「__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

16
32
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
32