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
相关产品推荐
相关产品推荐

