16
29

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

pathlibが便利すぎてもうos.pathは使えない件

Posted at

はじめに

こんにちは、@nano_sudoです!
今回は、Pythonの標準ライブラリであるpathlibを紹介します。(n番煎じ...)
タイトルは正直なところ、少し大げさですが、pathlibは、os.pathよりも便利なので、ぜひ使ってみてください!

pathlibとは

pathlibは、ファイルパスを扱うためのライブラリです。
pathlibを使うと、ファイルパスを文字列で扱うのではなく、オブジェクトとして扱うことができます。

os.pathじゃだめなの?

pathlibは、os.pathと比べて、次のようなメリットがあります。

  • 豊富なメソッド
    pathlibは、ファイルパスをオブジェクトとして扱うので、ファイルパスに対して様々な操作を行うことができます。

  • パスの区切り文字の違いを吸収してくれる
    pathlibは、OSによって異なるパスの区切り文字を吸収してくれます。
    例えば、Windowsでは\、Linuxでは/を使いますが、pathlibを使えば、どちらのOSでも同じコードで動作させることができます。

  • パスの結合が簡単
    pathlibは、/演算子を使ってパスを結合することができます。
    例えば、/演算子を使って/home/user/home/user/test.txtを結合すると、/home/user/test.txtとなります。

主要なクラス

pathlib-inheritance.png
pythonドキュメントより引用

基本的には、Pathクラスを使うことになりますが、 このクラスが出てきたときに混乱しないように、まずはクラスの構造を理解しておきましょう。

  • PurePath
    OSに依存しないパスを表現するためのクラス
  • PurePosixPath
    LinuxやMacOSのパスを表現するためのクラス
  • PureWindowsPath
    Windowsのパスを表現するためのクラス
  • Path
    PurePathを継承したクラスで、PurePathにファイルシステムの操作を追加したクラス
  • WindowsPath,PosixPath
    Pathを継承したクラスで、PathにOSに依存したファイルシステムの操作を追加したクラス
    親クラスは、OSに依存しないPureWindowsPath,PurePosixPathPath

早速使ってみる

パスの生成

pathlibは、Pathクラスを使ってパスを生成します。

from pathlib import Path

# 絶対パス
path = Path("/home/user/test.txt")

# 並べて書くと、結合される
path = Path("/home", "user", "test.txt") # /home/user/test.txt

# ただし、絶対パスを2つ以上並べて書くと、先に書いたパスは無視されるので注意
path = Path("/home", "/user", "test.txt") # /user/test.txt

# 相対パス
path = Path("test.txt")
# 現在のディレクトリ
path = Path.cwd()

パスの結合

/演算子を使ってパスを結合することができます。
(便利すぎて最初見たときは感動しました...)

from pathlib import Path

# Pathオブジェクト + Pathオブジェクト
path = Path("/home/user") / Path("test.txt")
# Pathオブジェクト + 文字列
path = Path("/home/user") / "test.txt"
# joinpathメソッド
path = Path("/home/user").joinpath("test.txt")

# 結合結果
print(path)  # /home/user/test.txt

パスの分解

from pathlib import Path

path = Path("/home/user/test.txt")

# ディレクトリ名
print(path.parent)  # /home/user
# ファイル名と拡張子
print(path.name)  # test.txt
# ファイル名(拡張子なし)
print(path.stem)  # test
# 拡張子
print(path.suffix)  # .txt

注意点としては、path.suffixtar.gzのような複数の拡張子には対応していないので、path.nameを使って自分で処理する必要があります。

パスの存在確認

os.path.existsと同じように、path.existsでパスの存在確認ができます。

from pathlib import Path

path = Path("/home/user/test.txt")

# パスが存在するか
print(path.exists())  # True
# パスがファイルか
print(path.is_file())  # True
# パスがディレクトリか
print(path.is_dir())  # False

相対パスと絶対パスの変換

Path.relative_to(<相対の基準となるパス>)で、絶対パスを相対パスに変換することができます。
Path.absolute()で、相対パスを絶対パスに変換することができます。
Path.resolve()で、...を含むパスを解決することができます。

from pathlib import Path

# 絶対パス
abspath = Path("/home/user/test.txt")
# 相対パス化
print(abspath.relative_to("/home"))  # user/test.txt

# 相対パス
relpath = Path("user/test.txt")
# 絶対パス化
print(relpath.absolute())  # /home/user/test.txt

# ..や.を含むパスを解決する
print(Path("user/../test.txt").resolve())  # /home/test.txt

パスの操作

pathlibでは、パスに対して様々な操作を行うことができます。

from pathlib import Path

path = Path("/home/user/test.txt")

# パスの移動・名前変更(上書きを行わない)
path.rename("/home/user/test2.txt")
# パスの移動・名前変更(上書きを行う)
path.replace("/home/user/test2.txt")
# パスの作成
path.mkdir() # parents=Trueで親ディレクトリも作成可能
# パスの削除
path.rmdir()

ファイルの操作

pathlibでは、ファイルに対して様々な操作を行うことができます。

from pathlib import Path

path = Path("/home/user/test.txt")

# ファイルの読み込み
path.read_text()
# ファイルの書き込み
path.write_text("Hello World!")
# ファイルの削除
path.unlink() # ディレクトリの場合はrmdir()

jsonを読み込む例

from pathlib import Path
import json

# ファイルの読み込み
path = Path("/home/user/test.json")
data = json.loads(path.read_text())
# ファイルの書き込み
path.write_text(json.dumps(data))

open()を使うよりも、pathlibを使った方が、簡潔に書くことができます。
特に、ファイルを閉じる処理を書く必要がないので、コードが簡潔になります。

情報の取得

from pathlib import Path

fpath = Path("/home/user/test.txt")

# ファイルのサイズ
print(fpath.stat().st_size)  # 11
# ファイルの更新日時
print(fpath.stat().st_mtime)  # 1620000000.0
# ファイルの作成日時
print(fpath.stat().st_ctime)  # 1620000000.0

dpath = Path("/home/user")

# ディレクトリの中身を取得
print(list(dpath.iterdir()))  # [PosixPath('/home/user/test.txt')]
# ディレクトリの中身を再帰的に取得
print(list(dpath.glob("**/*")))  # [PosixPath('/home/user/test.txt')]
# ファイルを再帰的に取得
print(list(dpath.glob("**/*.txt")))  # [PosixPath('/home/user/test.txt')]

まとめ

いかがでしたでしょうか?
pathlibは、複雑なファイル構造を扱うときに、いつも重宝しています。
ぜひ使ってみて、良きPythonライフを送ってください!
間違いや、不明点があれば、コメントまたは、@nano_sudoまでお願いします!

16
29
3

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
29

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?