You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

pickle序列化自定义Title类报PicklingError属性查找失败怎么办

问题说明

使用Python的pickle模块执行自定义类实例的序列化写入操作时抛出异常,错误提示__main__模块下Title类的属性查找失败。

复现代码

import pickle


class Title:
    def __init__(self, title, platform, size, price):
        self.title = title
        self.platform = platform
        self.size = size
        self.price = price

    def display(self):
        print("Printing the title details", '\n')
        print('TITLE:{} , PLATFORM:{}, SIZE:{} , PRICE:{}'
              .format(self.title, self.platform, self.size, self.price))


g = Title("Battlefield V", "Steam", "65GB", "1200")

""" Serialisation to be done of the instance g using pickle module"""

with open('game.csv', 'wb') as f:
    pickle.dump(g, f)
print('serialization is complete - file object created')

with open('game.ser', 'rb') as f:
    game_obj = pickle.load(f)
print('Deserialization is complete - python obj created')

game_obj.display()

报错信息

pickle.PicklingError: Can't pickle <class '__main__.Title'>: attribute lookup      Title on __main__ failed
错误原因
  1. 代码存在基础逻辑错误:序列化写入的文件名为game.csv,反序列化时却尝试读取game.ser,两个路径不一致,即使序列化成功也会触发文件不存在的错误。
  2. 触发属性查找失败的PicklingError核心原因是:pickle序列化自定义类时,要求被序列化的类必须定义在模块顶层作用域,执行序列化/反序列化操作时,Python解释器可以直接在当前模块的全局命名空间中定位到该类。该错误通常由以下不规范写法导致:
    • 将Title类定义写在函数、条件判断、循环等嵌套代码块内部,而非文件顶格的顶层位置
    • 在交互式运行环境(Python自带Shell、IPython、Jupyter Notebook)中逐行/逐块运行类定义和序列化代码,类未被正确注册到__main__模块的全局属性表
    • 保存代码的文件名和Python标准库重名(比如将脚本命名为pickle.py),导致import pickle时导入逻辑混乱
修复步骤
  • 检查Title类的定义位置,确保其在py文件中顶格编写,不嵌套在任何函数、分支、循环代码块内
  • 统一序列化、反序列化操作使用的文件路径,建议使用.pkl作为pickle序列化文件的专属后缀,避免和csv等其他格式文件混淆
  • 检查脚本文件名,不要命名为pickle.py,防止和标准库模块重名引发冲突
  • 不要在交互式环境中逐段运行这段涉及自定义类序列化的代码,将完整代码保存为独立py文件后执行

修复后可运行代码

import pickle


# 自定义类必须放在模块顶层作用域
class Title:
    def __init__(self, title, platform, size, price):
        self.title = title
        self.platform = platform
        self.size = size
        self.price = price

    def display(self):
        print("Printing the title details\n")
        print('TITLE:{} , PLATFORM:{}, SIZE:{} , PRICE:{}'
              .format(self.title, self.platform, self.size, self.price))


if __name__ == '__main__':
    g = Title("Battlefield V", "Steam", "65GB", "1200")
    # 统一序列化和反序列化使用的文件路径
    save_path = 'game.pkl'
    
    # 序列化写入
    with open(save_path, 'wb') as f:
        pickle.dump(g, f)
    print('serialization is complete - file object created')
    
    # 反序列化读取同一路径
    with open(save_path, 'rb') as f:
        game_obj = pickle.load(f)
    print('Deserialization is complete - python obj created')

    game_obj.display()

正常运行输出

serialization is complete - file object created
Deserialization is complete - python obj created
Printing the title details

TITLE:Battlefield V , PLATFORM:Steam, SIZE:65GB , PRICE:1200

内容的提问来源于stack exchange,提问作者Mandar Gite

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 14:27:18