Pythonのファイルおよびフォルダー操作

Pythonでよく使うファイル、フォルダーの操作のまとめ。標準ライブラリーの[Path](https://docs.python.org/ja/3/library/pathlib.html)または[shutil](https://docs.python.org/ja/3/library/shutil.html)を使います。Pathオブジェクトとは何かについては[こちら](https://note.nkmk.me/python-pathlib-usage/)。

# Pathオブジェクトの作り方
```python:インポートとオブジェクト作成
from pathlib import Path
import shutil

# カレントディレクトリーにあるfile.txtを取得。以下の3つは全て同じ結果。
p = Path('file.txt')
p = Path('./file.txt')
p = Path() / 'file.txt'

# 絶対パスでもOK
p = Path('c:/users/user01/documents/file.txt')

# フォルダーもOK
f = Path('c:/users/user01/documents')
```


# パスの情報取得

|やること|やり方|
|:--|:--|
| ファイル名                | [Path.name](https://docs.python.org/ja/3/library/pathlib.html#pathlib.PurePath.name)
| ファイル名（拡張子なし）  | [Path.stem](https://docs.python.org/ja/3/library/pathlib.html#pathlib.PurePath.stem)
| 拡張子                    | [Path.suffix](https://docs.python.org/ja/3/library/pathlib.html#pathlib.PurePath.suffix)
| 存在するかどうか           | [Path.exists()](https://docs.python.org/ja/3/library/pathlib.html#pathlib.Path.exists)
| ファイルかどうか           | [Path.is_file()](https://docs.python.org/ja/3/library/pathlib.html#pathlib.Path.is_file)
| フォルダーかどうか         | [Path.is_dir()](https://docs.python.org/ja/3/library/pathlib.html#pathlib.Path.is_dir)
| 絶対パス             | [Path.resolve()](https://docs.python.org/ja/3/library/pathlib.html#pathlib.Path.resolve)
| 親フォルダー          | [Path.parent](https://docs.python.org/ja/3/library/pathlib.html#pathlib.PurePath.parent)
| パターンに一致するか  | [Path.match()](https://docs.python.org/ja/3/library/pathlib.html#pathlib.PurePath.match)
| ファイルサイズ（Byte） | [Path.stat().st_size](https://docs.python.org/ja/3/library/pathlib.html#pathlib.Path.stat) 

# フォルダー内のパス取得

|やること|やり方|
|:--|:--|
| フォルダー内パスのイテレーション| [Path.iterdir()](https://docs.python.org/ja/3/library/pathlib.html#pathlib.Path.iterdir)
| パターンに一致するパス取得| [Path.glob()](https://docs.python.org/ja/3/library/pathlib.html#pathlib.Path.glob)


# ファイル、フォルダーのリネーム、コピー等

なぜPathだけでできないのか…

|やること| やり方<br>Path | やり方<br>shutil | 備考 |
|:--|:--|:--|:--|
| リネーム          | [Path.rename()](https://docs.python.org/ja/3/library/pathlib.html#pathlib.Path.rename) <br> [Path.replace()](https://docs.python.org/ja/3/library/pathlib.html#pathlib.Path.replace) | |リネーム後のファイルが存在する場合、Path.rename()は`FileExistsError`、Path.replace()は上書き。
| ファイルコピー    |               | [shutil.copy()](https://docs.python.org/ja/3/library/shutil.html#shutil.copy) | ・コピー先ファイルが存在する場合は上書き <BR> ・コピー先フォルダーが存在しない場合はエラー <BR> ・戻り値は新しく作成したファイル
| ファイル移動      |               | [shutil.move()](https://docs.python.org/ja/3/library/shutil.html#shutil.move) | 引数はstr（Python 3.9からPathオブジェクトも可）。引数`dst`はフォルダーでもファイルでもOK。移動先ファイルが存在すれば上書き。
| ファイル削除      | [Path.unlink()](https://docs.python.org/ja/3/library/pathlib.html#pathlib.Path.unlink) | 
| フォルダー作成    | [Path.mkdir()](https://docs.python.org/ja/3/library/pathlib.html#pathlib.Path.mkdir) | | ・戻り値は`None` <br>・*parents=True* で途中の親フォルダーも作成　<br> ・*exist_ok=True* で既にフォルダーが存在してもエラーとしない |
| フォルダーコピー  |               | [shutil.copytree()](https://docs.python.org/ja/3/library/shutil.html#shutil.copytree) | ・*src*フォルダーの中身を*dst*フォルダーにコピー（*dst*の下に*src*がコピーされる訳ではない） <BR> ・*dst*フォルダーが存在しなくてもOK <BR> ・*dirs_exist_ok=True*で既にフォルダーが存在してもエラーとしない
| フォルダー移動    |               | [shutil.move()](https://docs.python.org/ja/3/library/shutil.html#shutil.move)
| フォルダー削除    |               | [shutil.rmtree()](https://docs.python.org/ja/3/library/shutil.html#shutil.rmtree)


# その他
## 演算子 /

```python
# 演算子/で文字列と結合して新しいPathを生成
Path() / "folder1 / file1.txt"
```

## ファイルの親フォルダー

```python
# 実行中のファイルの親フォルダー
# Path() だとカレントディレクトリー（Path.cwd())となり、ファイルからの相対パスを設定できないこともある
Path(__file__).parent 
```

# 参考
- [Pathlibチートシート](https://qiita.com/meznat/items/a1cc61edb1e340d0b1a2)