メモ書き:斧頭氷杖だか漬物だかなんだか(pickle)

pythonのpickleの話です。
正直、どういうときに使うものなのかよくらからない。いや、分からないこともないこともないんですけどね。ええ。まあその話は下の方で書くとしまして。

ファイルに保存

import pickle
sepblectus = {"r":"", "o":"", "y":"", "g":"", "b":"Celen", "i":"Kya", "v":"Amy"}
with open("sep.pickle", "wb") as f:
    pickle.dump(sepblectus, f)

pythonオブジェクトならなんでもいい(らしい)。
調べたところ、どうやら別にバイナリモードで保存しなければいけないわけではないらしい。ずいぶん遠回しな書き方ですね。
簡単に言うと「バイナリモードの方が推奨されるのでそっちでやれ。あ、でも強制じゃないよ。」ってわけ。

読み込み

import pickle
with open("sep.pickle","rb") as f:
    d = pickle.load(f)
print(d)
{'r': '', 'o': '', 'y': '', 'g': '', 'b': 'Celen', 'i': 'Kya', 'v': 'Amy'}

「EOFError: Ran out of input」が表示された

pickle用に保存したファイルが空だった時にでるエラーらしい。そげなバカな………!?と思ってファイル確認したらたしかにファイルサイズが0kbだった。(原因未調査)
対処法がここに書いてあるような書いていないような気がしたけどあんまりしっくりこなかったので記憶貯蔵庫には書かない。

で、どういうときに使うの?

平たく言うと、Pythonオブジェクトをファイルとして保存し、呼び出せるようにすることができる形にするためのライブラリという事になります。

分かるようで分かりませんわ。分かるんだけど、完全に理解にしたにならないんですの。

DataFrameと使うときの注意

pandasのDataFrameをpickle化した後,pandasまたはPythonのバージョンを上げると,このpickleをloadした際に以下の様なエラーが起きることがあります.
ModuleNotFoundError: No module named 'pandas.indexes'

引用元:
https://estuarine.jp/2017/07/pickle_pandas_error/
なんかエラーはいたんだけど???ってなったので調べたらそういうことらしい。

pickle.UnpicklingError

こういうエラーがあるっぽい。調査中。
私の環境下で出たのは「invalid load key, '\x00'.」だった。
https://teratail.com/questions/154262
https://stackoverflow.com/questions/73056948/pickle-unpicklingerror-invalid-load-key-x00
いろいろ探しても「適切に保存されていない可能性がある」くらいしか出てこない。そういうものなのかも。
load keyにあたるものもいくつか種類があるようで。

基本放置させるものにはこれ用の例外処理とか書いておいた方が安全かもしれないと思った。

    try:
        with open (file,"rb") as f:
            status = pickle.load(f)
    except pickle.UnpicklingError:
        ErrorFileList.append(file)
        
    else:
        media = status.entities.get("media")

みたいな。

関数を読み込む?(メモ)

importしてるモジュールの関数は別モジュールから正しく呼べる
同じモジュール内の関数は同名の関数が呼ばれる

なお、test1.pyでtest1.pyをimportして、test1.funcをpickle保存すれば正しく読み込めるようになります。

qiita.com

推測(未確認)
  1. importで読み込んだ関数はpickleに保存して、読み込める
  2. importしていない関数はpickleに関数名のみ保存される
  3. そのため、 importしていない関数をpickle.load()→実行をすると、同名の関数が適用される
  4. 同様に、 importしていない関数をpickle.load()→実行をすると、同名の関数がない場合NameError: name 任意 is not definedになる