[Python] os.path によるパス操作

Python os
Python
スポンサーリンク

ファイルやディレクトリの存在を確認したり、パスの結合や分割をしたり、ファイル名やパスを確認したりする操作は、よく使用する機能の1つです。

そこで今回は、os.path を使用したパス操作について説明をします。

環境

Python 3.9.1

VSCode1.52.1

os.path を使用する上での事前準備

パスを操作するには、os.path を使用します。

まずは、以下のようにして os.path をインポートします(本記事のコードはこれを採用)。

from os import path

path をインポートすることで、path.xxx のように記述してパスの操作をすることができます。
もしくは、以下のように os のインポートでも構いません。この場合は、os.path.xxx とする必要があります。

import os

絶対パスを取得する(abspath(path))

絶対パスを取得するには、abspath(path) を使用します。

以下は、現在のカレントディレクトリ「./」を指定して、その絶対パスを取得しています。

>>> path.abspath('./')
'/Users/hiro/Desktop/python'

パスの末尾を取得する(basename(path))

パスの末尾を取得するには、basname(path) を使用します。

以下は末尾がファイル名のパスを指定する例です。ファイル名「app.log」を取得できます。

>>> path.basename('/Users/Library/Logs/app.log')
'app.log'

以下は末尾がディレクトリの場合のパスを指定する例です。ディレクトリ名「Logs」を取得できます。

>>> path.basename('/Users/Library/Logs')
'Logs'

リストで共通するパス部分を取得する(commonpath(list))

リスト内のすべてのパスに共通する部分を取得するには commonpath(list) を使用します。

たとえば、「/Users/Library」と「Users/Log」がリストで指定されている場合は「/Users」までを共通パスと判断して返します。

>>> path.commonpath(['/Users/Library','/Users/Log'])
'/Users'

リストで共通するパス部分を取得する(commonprefix(list))

リスト内のすべてのパスに共通する接頭辞のうち、もっとも長い部分を取得するには commonprefix(list) を使用します。前述した commonpath(list) はパスとして認識できる部分を返すのに対し、commonprefix(list) は文字列として一致する部分を返します。

たとえば、「/Users/Library」と「Users/Log」がリストで指定されている場合は、両方に一致する接頭辞「/Users/L」を返します。

>>> path.commonprefix(['/Users/Library','/Users/Log'])
'/Users/L'

パスのディレクトリ名を取得する(dirname(path))

パス文字列からディレクトリ名を取得するには dirname(path) を使用します。返される値はsplit() にパスを渡した時に返される値の 1 番めの要素と同じです。
たとえば、「/Users/Library/Logs」というパスを渡すと、「/Users/Library」が返されます。

>>> path.dirname('/Users/Library/Logs')
'/Users/Library'

パスの存在を確認する(exists(path))

パスの存在(実在するかどうか)を確認するには exists(path) を使用します。

指定したパスが存在する場合は True を、存在しない場合は False を返します。また、シンボリックリンクが壊れている場合は False を返します。

>>> path.exists('/Users/Library/Logs')
True

チルダ(~)が含まれたパスをフルパスに変換する(expanduser(path))

Unix や Windows では、先頭にチルダ(~)があるようなパスを見かけることがあります。

このようなパスからフルパスを取得するには、expanduser(path) を使用します。置き換えに失敗したり、引数のパスがチルダで始まっていない場合は、パスをそのまま返します。

>>> path.expanduser('~/')
'/Users/hiro/'

環境変数を展開する(expandvars(path))

環境変数 $HOME や $PATH を実際のパスに置換するには、expandvars(path) を使用します。

>>> path.expandvars('$HOME')
'/Users/hiro'
>>> path.expandvars('$PATH')
'/Users/hiro/.pyenv/shims:/Users/hiro/.pyenv/bin'

パスに最後にアクセスした時刻を取得する(getatime(path))

パスに最後にアクセスした時刻を取得するには getatime(path) を使用します。

>>> path.getatime('/Users/hiro/desktop')
1609657100.7394705

実行してみるとわかりますが、160965… と訳のわからない数値がならんでいます。
geatime はエポック秒というものを返します。エポック秒とは、Unix時間の1970年1月1日0時0分0秒からの経過秒数とのことです。そこで time モジュールを使ってエポック秒からローカル時間に変換をします。

>>> import time
>>> time.localtime(path.getatime('/Users/hiro/desktop'))
time.struct_time(tm_year=2021, tm_mon=1, tm_mday=3, tm_hour=15, tm_min=58, tm_sec=20, tm_wday=6, tm_yday=3, tm_isdst=0)

time.localtime を使用することで年月日時分秒、曜日、年内の通し日数、サマータイムの有無などの情報を返すようになります。しかし、このままの情報ではわかりにくいので関数 strftime を使用して time.struct_time 時刻値シーケンスの型から形式を指定して文字列に変換します。

書式 説明
%a ロケールの曜日名を省略形で表示。
%A ロケールの曜日名を表示。
%b ロケールの月名を省略形で表示。
%B ロケールの月名を表示。
%c ロケールの適切な日付および時刻の表示。
%d 10進数で月の始めから何日目かを表示。
%f 10進数でマイクロ秒を表示。
%G ISO weekの内過半数を含んだ西暦表記のISO 8601 year。
%H 10進数で24時間計での時を表示。
%I 10進数で12時間計での時を表示。
%j 10進数で年の初めから何日目かを表示。
%m 10進数で月を表示。
%M 10進数で分を表示。
%p ロケールのAM・PMに対応する文字列。
&S 10進数で秒を表示。
%u 月曜日を1とする10進数表記のISO 8601 weekday。
%U 10進数で年の初めから何週目かを表示。年明けから最初の日曜日までの全ての曜日は0週目。
%w 曜日を10進表記した文字列を表示。表示は日曜日が0・土曜日が6。
%W 10進数で年の初めから何週目かを表示。年明けから最初の月曜日までの全ての曜日は0週目。
%x ロケールの適切な日付を表示。
%X ロケールの適切な時刻を表示。
%y 10進数で上2桁のない西暦年を表示。
%Y 10進数で上2桁が付いている西暦年を表示。
%Z タイムゾーン名。タイムゾーンがない場合は空文字列。
%% 文字「%」を表示。

以下に strftime を使用してわかりやすい書式に変換する例を示します。

>>> import time
>>> from time import strftime
>>> 
>>> strftime("%a, %d %b %Y %H:%M:%S", time.localtime(path.getatime('/Users/hiro/desktop')))
'Sun, 03 Jan 2021 15:58:20'

パスの更新日時を取得する(getmtime(path))

パスの更新日時を取得するには getmtime(path) を使用します。使用方法は前述のgetatime(path) と同様ですので詳細は割愛します。

>>> import time
>>> from time import strftime
>>> 
>>> strftime("%a, %d %b %Y %H:%M:%S", time.localtime(path.getmtime('/Users/hiro/desktop')))
'Sun, 03 Jan 2021 15:58:20'

パスの作成日時を取得する(getctime(path))

パスの更新日時を取得するには getctime(path) を使用します。使用方法は前述の getatime(path) と同様ですので詳細は割愛します。

>>> import time
>>> from time import strftime
>>> 
>>> strftime("%a, %d %b %Y %H:%M:%S", time.localtime(path.getctime('/Users/hiro/desktop')))
'Sun, 03 Jan 2021 15:58:20'

ファイルのサイズを取得する(getsize(path))

ファイルサイズを取得するには getsize(path) を使用します。返される値の単位は「バイト」です。

>>> path.getsize('/Users/hiro/desktop/python/log/app.log')
376

指定したパスが、絶対パスかどうかを判断する(isabs(path))

指定したパスが絶対パスかどうかを判断するには isabs(path) を使用します。絶対パスの場合は true を返します。Unixの場合は / ではじまり、Windows の場合は ドライブレターに続く¥ ではじまるパスです。

>>> path.isabs('/Users/hiro/desktop/python/')
True
>>> path.isabs('Users/hiro/desktop/python/')
False

ファイルの存在を確認する(isfile(path))

ファイルが存在するかどうかを確認するには isfile(path) を使用します。ファイルが存在する場合は True を返します。

>>> path.isfile('/Users/hiro/desktop/python/log/app.log')
True
>>> path.isfile('/Users/hiro/desktop/python/log/app2.log')
False

ディレクトリの存在を確認する(isdir(path))

ディレクトリが存在するかどうかを確認するには isdir(path) を使用します。ディレクトリが存在する場合は True を返します。

>>> path.isdir('/Users/hiro/desktop/python')
True
>>> path.isdir('/Users/hiro/desktop/py')
False

シンボリックリンクの存在を確認する(islink(path))

指定したシンボリックリンクが存在するかどうかを確認するには islink(path) を使用します。シンボリックリンクが存在する場合は True を返します。

>>> path.islink('/Users/hiro/Python')
True

パス文字列を結合する(join(path, path*))

パス文字列を結合して新しいパス文字列を作成するには join(path, path*) を使用します。引数は2つ以上指定することができます。

「/Users」と「hiro」の2つの文字列を結合して新しいパスを作成する例を以下に示します。

>>> path.join('/Users','hiro')
'/Users/hiro'

「/Users」と「hiro」と「python」の3つの文字列を結合して新しいパスを作成する例を以下に示します。

>>> path.join('/Users','hiro','python')
'/Users/hiro/python'

「/Users」と「/hiro」の場合は、どちらもルートパスを指していますので結合ができず、最後の「/hiro」が残ります。

>>> path.join('/Users','/hiro')
'/hiro'

パスを正規化する(normpath(path))

パスを正規化するには normpath(path) を使用します。ドキュメントによる A//B、A/B/、A/./B や A/foo/../B などはすべて A/B になるとのことです。
以下に例を示します。

>>> path.normpath('/Users//python')
'/Users/python'
>>> path.normpath('/Users/python/')
'/Users/python'
>>> path.normpath('/Users/./python')
'/Users/python'
>>> path.normpath('/Users/foo/../python')
'/Users/python'

相対パスを取得する(relpath(path, start=os.curdir)

相対パスを取得するには relpath(path, start=os.curdir) を使用します。start ディレクトリからの path への相対パスを返します。start ディイレクトリを省略した場合はカレントディレクトリからの相対パスを返します。

>>> path.relpath('/Users/hiro')
'../..'

2つのパスが同じかを調べる(samefile(path1, path2))

2つのパス(ディレクトリ or ファイル)が同じかどうかを調べるには samefile(path1, path2) を使用します。同一の場合は True を返します。

>>> path.samefile('/Users/hiro','/Users/hiro')
True

異なるパスの場合には、以下のように No such file or directory のエラーが発生します。

>>> path.samefile('/Users/hiro','/Users/hiro2')
Traceback (most recent call last):
  File "", line 1, in 
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/genericpath.py", line 101, in samefile
    s2 = os.stat(f2)
FileNotFoundError: [Errno 2] No such file or directory: '/Users/hiro2'

パスを head と tail に分割する(split(path))

パス名を (head, tail) のペアに分割するには split(path) を使用します。 tail はパス名の構成要素の末尾で、 head はそれより前の部分を示します。なお tail はスラッシュを含みません。

>>> path.split('/Users/hiro/Desktop/python/app1.log')
('/Users/hiro/Desktop/python', 'app1.log')

パスを drive と tail に分割する(splitdrive(path))

パス名 path を (drive, tail) のペアに分割するには splitdrive(path) を使用します。drive はマウントポイントか空文字列になります。ドライブをサポートしていないシステムは、drive は常に空文字になります。

>>> path.splitdrive("C:¥Work") 
('C:', '¥Work')

パスから拡張子を取得する(splitext(path))

パスから拡張子を取得するには splitext(path) を使用します。ピリオドが含まれていない場合は、path に与えたパス文字列と空文字のペアを返します。

>>> path.splitext('/Users/hiro/Desktop/python/app1.log')
('/Users/hiro/Desktop/python/app1', '.log')
Please follow and like us:

コメント

タイトルとURLをコピーしました