本文介绍了从Python 2中的Python 3取消选择类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果使用协议2对Python 3类进行腌制,应该可以在Python 2中使用它,但是不幸的是,由于某些类的名称已更改,因此失败了.

If a Python 3 class is pickled using protocol 2, it is supposed to work in Python 2, but unfortunately, this fails because the names of some classes have changed.

假设我们有如下代码.

发件人

pickle.dumps(obj,2)

接收器

pickle.loads(atom)

要给出具体情况,如果为obj={},则给出的错误为:

To give a specific case, if obj={}, then the error given is:

这是因为Python 2改用了__builtin__.

This is because Python 2 uses __builtin__ instead.

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

The question is the best way to fix this problem.

推荐答案

此问题是 Python问题3675 ​​.这个错误实际上是在Python 3.11中修复的.

This problem is Python issue 3675. This bug is actually fixed in Python 3.11.

如果我们导入:

from lib2to3.fixes.fix_imports import MAPPING

MAPPING将Python 2名称映射到Python 3名称.我们要相反.

MAPPING maps Python 2 names to Python 3 names. We want this in reverse.

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

我们可以覆盖Unpickler并加载

We can override the Unpickler and loads

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()

然后我们将此负载称为pickle.loads.

We then call this loads instead of pickle.loads.

这应该可以解决问题.

这篇关于从Python 2中的Python 3取消选择类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 19:54