【问题标题】:Unpickling classes from Python 3 in Python 2在 Python 2 中从 Python 3 中提取类
【发布时间】:2010-11-25 23:39:57
【问题描述】:

如果 Python 3 类使用协议 2 腌制,它应该在 Python 2 中工作,但不幸的是,由于某些类的名称已更改,这会失败。

假设我们有如下代码。

发件人

pickle.dumps(obj,2)

接收者

pickle.loads(atom)

给出一个具体的案例,如果obj={},那么给出的错误是:

ImportError: 没有名为 builtins 的模块

这是因为 Python 2 使用了__builtin__。

问题是解决此问题的最佳方法。

【问题讨论】:

    标签: python python-3.x pickle


    【解决方案1】:

    这个问题是Python issue 3675。这个错误实际上已在 Python 3.11 中修复。

    如果我们导入:

    from lib2to3.fixes.fix_imports import MAPPING
    

    MAPPING 将 Python 2 名称映射到 Python 3 名称。我们希望反过来。

    REVERSE_MAPPING={}
    for key,val in MAPPING.items():
        REVERSE_MAPPING[val]=key
    

    我们可以覆盖 Unpickler 并加载

    class Python_3_Unpickler(pickle.Unpickler):
        """Class for pickling objects from Python 3"""
        def find_class(self,module,name):
            if module in REVERSE_MAPPING:
                module=REVERSE_MAPPING[module]
            __import__(module)
            mod = sys.modules[module]
            klass = getattr(mod, name)
            return klass
    
    def loads(str):
        file = pickle.StringIO(str)
        return Python_3_Unpickler(file).load()  
    

    然后我们将其称为 load 而不是 pickle.loads。

    这应该可以解决问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-05-15
      • 1970-01-01
      • 2020-01-19
      • 1970-01-01
      • 2018-03-22
      • 1970-01-01
      • 2016-11-30
      相关资源
      最近更新 更多