プロジェクト

全般

プロフィール

12章学習記録 » 履歴 » バージョン 3

Tatsuya ISHIGAKI, 2025/07/25 07:47

1 1 Tatsuya ISHIGAKI
## 12.3 tar ファイルを扱う tarfile
2
gzip, bz2, lzma 形式で圧縮されたものを含む、tar 形式アーカイブを読み書きする
3
4
- tar ファイルを操作する
5
  - 関数 `open(name=None, mode='r', fileobj=None, bufsize=20240, **kwargs)`
6
    - `name` tar ファイルのファイル名
7
    - `mode` モード指定 `r` `w` 等
8
      - 圧縮形式を指定する場合は `r:gz` `w:xz` 等 (非圧縮指定は `w:` 等)
9
      - 読み込み時は `r` だけでも、ファイル名拡張子から圧縮形式が自動判定される
10
      - 圧縮ファイルは追記モードが使用できない (`a` `a:` のみ)
11
    - `fileobj` tar ファイルのファイルオブジェクト
12
    - `bufsize` ブロックサイズ (デフォルトでよい)
13
    - **戻り値** `tarfile.TarFile`
14
  - 関数 `is_tarfile(name)`
15
    - `name` ファイル名、または file-like オブジェクト
16
    - **戻り値** (bool) 指定ファイルが tar 形式アーカイブなら True
17
  - `TarFile` オブジェクトのメソッド
18
  
19
    |メソッド名|解説|戻り値|
20
    |---|---|---|
21
    |`getnames()`|tar ファイル内にアーカイブされているファイル名リスト|list|
22
    |`getmember(name)`|指定ファイル名の `TarInfo` を返す|TarInfo|
23
    |`getmembers()`|tar ファイル内にアーカイブされている全ファイルの `TarFile` のリストを返す|list|
24
    |`extract(member, path="", set_attrs=True, *, numeric_owner=False)`|指定ファイルを指定場所へ展開<br>`member`:ファイル名または`TarInfo`|None|
25
    |`extractall(path="", set_attrs=True, *, numeric_owner=False)`|全ファイルを指定場所へ展開|None|
26
    |`extractfile(member)`|指定ファイルを開き、ファイルオブジェクトを返す<br>`member`:ファイル名または`TarInfo`|ファイルオブジェクト|
27
    |`add(name, arcname=None, recursive=True, exclude=None, *, filter=None)`|指定ファイルを tar ファイルのアーカイブへ追加する<br>`arcname`を指定するとそのファイル名で追加<br>ディレクトリ指定では再帰追加可能|?|
28
    |`close()`||None|
29
30
    ```python
31
    >>> import tarfile
32
    >>> with tarfile.open("./testarchive.tar", "w:gz") as f:
33
    ...     f.add("./inArchive1.txt")
34
    ...
35
    >>> with tarfile.open("./testarchive.tar") as f:
36
    ...     f.getnames()
37
    ...     f.getmembers()
38
    ...
39
    ['./inArchive1.txt']
40
    [<TarInfo './inArchive1.txt' at 0x140b4104640>]
41
    >>> with tarfile.open("./testarchive.tar") as f:
42
    ...     with f.extractfile("./inArchive1.txt") as elem:
43
    ...         elem.read().decode("sjis")
44
    ...
45
    'アーカイブ内ファイル1'
46
    >>> with tarfile.open("./testarchive.tar") as f:
47
    ...     info = f.getmember("./inArchive1.txt")
48
    ...     info
49
    ...     print(f"{info.name=}, {info.size=}, {info.mtime=}, {info.mode=:o}")
50
    ...
51
    <TarInfo './inArchive1.txt' at 0x140b4104940>
52
    info.name='./inArchive1.txt', info.size=22, info.mtime=1753410842.0, info.mode=666
53
    >>> with tarfile.open("./testarchive.tar") as f:
54
    ```
55 2 Tatsuya ISHIGAKI
56
## 12.4 Python オブジェクトをシリアライズする pickle
57
Python オブジェクトをファイル等に保存可能なバイト列に変換 (**pickle 化** という)、復元 (**非 pickle 化** という) する
58
59
- JSON へのシリアライズ方法である json モジュールとの比較
60
  - JSON は文字列だが、pickle はバイナリ
61
  - JSON は他のプログラミング言語でも利用可能だが、pickle は Python 固有フォーマット
62
  - JSON は文字列、数値など一部のデータ型のみ扱うが、pickle は Python の様々なオブジェクトを扱える
63
64
- Python オブジェクトのシリアライズとデシリアライズ
65
66
  |関数名|解説|戻り値|
67
  |---|---|---|
68
  |`dump(obj, file, protocol=None, *, fix_imports=True, buffer_callback=None)`|オブジェクトをシリアライズしてファイルへ保存する|None|
69
  |`dumps(obj, protocol=None, *, fix_import=True, buffer_callback=None)`|オブジェクトをシリアライズしてバイト列を返す|bytes|
70
  |`load(file, *, fix_imports=True, encoding="ASCII", errors="strict", buffers=None)`|ファイルの中身をデシリアライズし、結果オブジェクトを返す|object|
71
  |`loads(data, /, *, fix_imports=True, encoding="ASCII", errors="strict", buffers=None)`|バイト列をデシリアライズし、結果オブジェクトを返す|object|
72
73
  dumps, loads (bytes でのやり取り) の例
74
  ```python
75
  >>> import pickle
76
  >>> from datetime import datetime
77
  >>> now = datetime.now()
78
  >>> data = {"NOW-date": now}  # 値が datetime の辞書データ作成
79
  >>> type(data)
80
  <class 'dict'>
81
  >>> data
82
  {'NOW-date': datetime.datetime(2025, 7, 25, 16, 4, 0, 201811)}
83
  >>> serialized = pickle.dumps(data)  # シリアライズ
84
  >>> serialized
85
  b'\x80\x04\x958\x00\x00\x00\x00\x00\x00\x00}\x94\x8c\x08NOW-date\x94\x8c\x08datetime\x94\x8c\x08datetime\x94\x93\x94C\n\x07\xe9\x07\x19\x10\x04\x00\x03\x14S\x94\x85\x94R\x94s.'
86
  >>> desirialized = pickle.loads(serialized)  # デシリアライズ
87
  >>> type(desirialized)
88
  <class 'dict'>
89
  >>> desirialized  # 元のデータを復元できている
90
  {'NOW-date': datetime.datetime(2025, 7, 25, 16, 4, 0, 201811)}
91
  ```
92
93
  dump, load (ファイルでのやり取り) の例
94
  ```python
95
  >>> data  # 対象データ
96
  {'NOW-date': datetime.datetime(2025, 7, 25, 16, 4, 0, 201811)}
97
  >>> with open("nowdate.pkl", "wb") as f:
98
  ...     pickle.dump(data, f)  # シリアライズしてファイルへ書き込み
99
  ...
100
  >>> with open("nowdate.pkl", "rb") as f:
101
  ...     obj = pickle.load(f)  # ファイル内容をデシリアライズ
102
  ...
103
  >>> obj  # 復元を確認
104
  {'NOW-date': datetime.datetime(2025, 7, 25, 16, 4, 0, 201811)}
105
  ```
106
107
  `dump()` で生成されたファイルの様子
108 3 Tatsuya ISHIGAKI
  ![nowdata.jpg](nowdate.jpg "nowdata.pkl")
109 2 Tatsuya ISHIGAKI
110
  - ※ pickle 化にはプロトコルのバージョンが 0 から 5 まであり、新しいバージョンで pickle 化されたオブジェクトは古いバージョンで非 pickle 化できない (`pickle.DEFAULT_PROTOCOL` でデフォルト確認可能)