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

Python2转Python3时wx应用shelve反序列化Rect TypeError问题

wxPython绘图应用Python2转Python3的shelve反序列化Rect错误问题
  • 基于wxPython的绘图应用,支持在画布绘制各类对象、点击编辑参数,关闭时用shelve库保存修改,Python2环境下运行正常。
  • 迁移到Python3后,添加一种仅用于图标间连线的特定对象,保存文件正常,但重新打开项目时失败。
  • 报错为反序列化shelf对象时的TypeError,提示Rect()参数不匹配,无完整调用栈。
  • 特殊现象:Python2生成的文件经转换后可打开,但再次保存关闭后仍会触发该错误。
  • 已自定义继承pickle.Unpickler的类,重写find_class方法处理模块重命名(将wx._gdi映射到wx),且代码中未直接调用Rect,问题排查难度大。

报错详情

File "\Unpickle.py", line 25, in renamed_load
    return RenameUnpickler(file_obj, encoding=encoding).load()
TypeError: Rect(): arguments did not match any overloaded call:
  overload 1: too many arguments
  overload 2: not enough arguments
  overload 3: argument 1 has unexpected type 'float'
  overload 4: argument 1 has unexpected type 'float'
  overload 5: argument 1 has unexpected type 'float'
  overload 6: argument 1 has unexpected type 'float'

相关读取操作代码

class RenameUnpickler(pickle.Unpickler):
    def find_class(self, module, name):
        renamed_module = module
        if module == "wx._gdi":
            renamed_module = "wx"
        return super(RenameUnpickler, self).find_class(renamed_module, name)

def renamed_load(file_obj, encoding):
    return RenameUnpickler(file_obj, encoding=encoding).load()

def renamed_loads(pickled_bytes):
    file_obj = io.BytesIO(pickled_bytes)
    return renamed_load(file_obj)

class ShelfFileVO( shelve.DbfilenameShelf ):

    def __init__(self, *args, **kwds):
        kwds[ 'protocol' ] = 2
        shelve.DbfilenameShelf.__init__( self, *args, **kwds )
        self._semaphore = threading.BoundedSemaphore( 1 )
        self.find_globals = None

    def keys(self):
        return [ k.decode() for k in self.dict.keys() ]

    def has_key(self, key):
        return key.encode() in self.dict

    def __contains__(self, key):
        return key.encode() in self.dict

    def get(self, key, default=None):
        #key = key.encode()
        if key in self.dict:
            return self[ key ]
        else:
            return default

    def __getitem__(self, key):
        #key = key.encode()
        if key in list(self.cache.keys()):
            value = self.cache[ key ]
        else:
            f = BytesIO( self.dict[ key ] )
            value = renamed_load(f, encoding='latin1')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 10:32:42