プロジェクト

全般

プロフィール

12章学習記録 » 履歴 » リビジョン 2

リビジョン 1 (Tatsuya ISHIGAKI, 2025/07/25 03:03) → リビジョン 2/4 (Tatsuya ISHIGAKI, 2025/07/25 07:45)

## 12.3 tar ファイルを扱う tarfile 
 gzip, bz2, lzma 形式で圧縮されたものを含む、tar 形式アーカイブを読み書きする 

 - tar ファイルを操作する 
   - 関数 `open(name=None, mode='r', fileobj=None, bufsize=20240, **kwargs)` 
     - `name` tar ファイルのファイル名 
     - `mode` モード指定 `r` `w` 等 
       - 圧縮形式を指定する場合は `r:gz` `w:xz` 等 (非圧縮指定は `w:` 等) 
       - 読み込み時は `r` だけでも、ファイル名拡張子から圧縮形式が自動判定される 
       - 圧縮ファイルは追記モードが使用できない (`a` `a:` のみ) 
     - `fileobj` tar ファイルのファイルオブジェクト 
     - `bufsize` ブロックサイズ (デフォルトでよい) 
     - **戻り値** `tarfile.TarFile` 
   - 関数 `is_tarfile(name)` 
     - `name` ファイル名、または file-like オブジェクト 
     - **戻り値** (bool) 指定ファイルが tar 形式アーカイブなら True 
   - `TarFile` オブジェクトのメソッド 
  
     |メソッド名|解説|戻り値| 
     |---|---|---| 
     |`getnames()`|tar ファイル内にアーカイブされているファイル名リスト|list| 
     |`getmember(name)`|指定ファイル名の `TarInfo` を返す|TarInfo| 
     |`getmembers()`|tar ファイル内にアーカイブされている全ファイルの `TarFile` のリストを返す|list| 
     |`extract(member, path="", set_attrs=True, *, numeric_owner=False)`|指定ファイルを指定場所へ展開<br>`member`:ファイル名または`TarInfo`|None| 
     |`extractall(path="", set_attrs=True, *, numeric_owner=False)`|全ファイルを指定場所へ展開|None| 
     |`extractfile(member)`|指定ファイルを開き、ファイルオブジェクトを返す<br>`member`:ファイル名または`TarInfo`|ファイルオブジェクト| 
     |`add(name, arcname=None, recursive=True, exclude=None, *, filter=None)`|指定ファイルを tar ファイルのアーカイブへ追加する<br>`arcname`を指定するとそのファイル名で追加<br>ディレクトリ指定では再帰追加可能|?| 
     |`close()`||None| 

     ```python 
     >>> import tarfile 
     >>> with tarfile.open("./testarchive.tar", "w:gz") as f: 
     ...       f.add("./inArchive1.txt") 
     ... 
     >>> with tarfile.open("./testarchive.tar") as f: 
     ...       f.getnames() 
     ...       f.getmembers() 
     ... 
     ['./inArchive1.txt'] 
     [<TarInfo './inArchive1.txt' at 0x140b4104640>] 
     >>> with tarfile.open("./testarchive.tar") as f: 
     ...       with f.extractfile("./inArchive1.txt") as elem: 
     ...           elem.read().decode("sjis") 
     ... 
     'アーカイブ内ファイル1' 
     >>> with tarfile.open("./testarchive.tar") as f: 
     ...       info = f.getmember("./inArchive1.txt") 
     ...       info 
     ...       print(f"{info.name=}, {info.size=}, {info.mtime=}, {info.mode=:o}") 
     ... 
     <TarInfo './inArchive1.txt' at 0x140b4104940> 
     info.name='./inArchive1.txt', info.size=22, info.mtime=1753410842.0, info.mode=666 
     >>> with tarfile.open("./testarchive.tar") as f: 
     ``` 

 ## 12.4 Python オブジェクトをシリアライズする pickle 
 Python オブジェクトをファイル等に保存可能なバイト列に変換 (**pickle 化** という)、復元 (**非 pickle 化** という) する 

 - JSON へのシリアライズ方法である json モジュールとの比較 
   - JSON は文字列だが、pickle はバイナリ 
   - JSON は他のプログラミング言語でも利用可能だが、pickle は Python 固有フォーマット 
   - JSON は文字列、数値など一部のデータ型のみ扱うが、pickle は Python の様々なオブジェクトを扱える 

 - Python オブジェクトのシリアライズとデシリアライズ 

   |関数名|解説|戻り値| 
   |---|---|---| 
   |`dump(obj, file, protocol=None, *, fix_imports=True, buffer_callback=None)`|オブジェクトをシリアライズしてファイルへ保存する|None| 
   |`dumps(obj, protocol=None, *, fix_import=True, buffer_callback=None)`|オブジェクトをシリアライズしてバイト列を返す|bytes| 
   |`load(file, *, fix_imports=True, encoding="ASCII", errors="strict", buffers=None)`|ファイルの中身をデシリアライズし、結果オブジェクトを返す|object| 
   |`loads(data, /, *, fix_imports=True, encoding="ASCII", errors="strict", buffers=None)`|バイト列をデシリアライズし、結果オブジェクトを返す|object| 

   dumps, loads (bytes でのやり取り) の例 
   ```python 
   >>> import pickle 
   >>> from datetime import datetime 
   >>> now = datetime.now() 
   >>> data = {"NOW-date": now}    # 値が datetime の辞書データ作成 
   >>> type(data) 
   <class 'dict'> 
   >>> data 
   {'NOW-date': datetime.datetime(2025, 7, 25, 16, 4, 0, 201811)} 
   >>> serialized = pickle.dumps(data)    # シリアライズ 
   >>> serialized 
   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.' 
   >>> desirialized = pickle.loads(serialized)    # デシリアライズ 
   >>> type(desirialized) 
   <class 'dict'> 
   >>> desirialized    # 元のデータを復元できている 
   {'NOW-date': datetime.datetime(2025, 7, 25, 16, 4, 0, 201811)} 
   ``` 

   dump, load (ファイルでのやり取り) の例 
   ```python 
   >>> data    # 対象データ 
   {'NOW-date': datetime.datetime(2025, 7, 25, 16, 4, 0, 201811)} 
   >>> with open("nowdate.pkl", "wb") as f: 
   ...       pickle.dump(data, f)    # シリアライズしてファイルへ書き込み 
   ... 
   >>> with open("nowdate.pkl", "rb") as f: 
   ...       obj = pickle.load(f)    # ファイル内容をデシリアライズ 
   ... 
   >>> obj    # 復元を確認 
   {'NOW-date': datetime.datetime(2025, 7, 25, 16, 4, 0, 201811)} 
   ``` 

   `dump()` で生成されたファイルの様子 
   ![nowdata.jpg](./chapter12/nowdate.jpg "nowdata.pkl") 

   - ※ pickle 化にはプロトコルのバージョンが 0 から 5 まであり、新しいバージョンで pickle 化されたオブジェクトは古いバージョンで非 pickle 化できない (`pickle.DEFAULT_PROTOCOL` でデフォルト確認可能)