6

プロトコル 2 を使用して Python 3 クラスを pickle 化すると、Python 2 でも動作するはずですが、残念ながら、一部のクラスの名前が変更されているため、これは失敗します。

次のように呼び出されるコードがあるとします。

送信者

pickle.dumps(obj,2)

レシーバー

pickle.loads(atom)

特定のケースを与えるために、 の場合、obj={}与えられたエラーは次のとおりです。

ImportError: builtins という名前のモジュールがありません

これは、Python 2 が__builtin__代わりに使用するためです。

質問は、この問題を解決するための最良の方法です。

4

1 に答える 1

14

この問題は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()  

これを pickle.loads の代わりに load と呼びます。

これで問題は解決するはずです。

于 2009-09-06T07:18:45.133 に答える