Watch at Ease看見世界,讀懂生活。

科技 · 實用指南

Python 顯示「Can’t pickle local object」?換序列化器前先證明程序邊界

例外指出子程序無法重建的物件,而不是平台專用答案。先記錄啟動方式、可呼叫物件、參數圖與匯入路徑。

Original technical diagram of Python process serialization boundaries.
原創插畫:證明 launcher、callable、argument 與 worker import 邊界。 Watch at Ease

這個例外表示跨程序傳送的物件無法序列化或按名稱解析;可能是巢狀函式、lambda、closure、bound method、lock、socket或捕獲它們的instance。

從實際launcher建立證據表,記錄Python與library版本、start method、module、qualified name、參數類型及fresh child import結果。

1. 固定真實launcher與start method

用相同script、test runner、notebook、IDE、service或framework重現,記錄python -VV、sys.executable、context與get_start_method()。

保留完整traceback並標出失敗是在start、map、submit、queue、result或framework worker startup。

2. 找到精確callable與object graph

記錄type(fn)、__module__與__qualname__;包含<locals>或<lambda>就是不可按module解析的證據。

分別測試callable與每個argument,只記錄第一個失敗type和安全結構路徑。

3. 在fresh interpreter證明可匯入

將最小worker entrypoint移到module top level,process creation放在main guard之下,確保production package path可匯入。

使用同一interpreter與working directory開新程序並解析qualified name,不依賴notebook state或IDE path。

4. 將parent resource與plain data分開

bound method可能攜帶整個instance。lock、file、socket、client與connection通常應在child建立。

若callable可匯入但argument失敗,傳遞小型plain record,並在worker initializer重建resource。

5. 將start method與serializer視為範圍決策

fork讓Linux測試通過不等於portable contract,對threaded library也可能不安全。

cloudpickle或dill改變dependency、compatibility與trust,僅在明確需求與受信receiver下使用。

6. 要求fresh-worker exit test

用相同production launcher與start method執行確定性小task,驗證import、input、result和clean exit。

記錄interpreter、start method、qualified name、input schema、worker PID、result checksum與exit status。

Original decision diagram for Python process serialization repairs.
原創插畫:只修復已證明的邊界,並用 fresh worker 重測。 Watch at Ease