2009-09-06 3 views
5

Если класс Python 3 маринован с использованием протокола 2, он должен работать в Python 2, но, к сожалению, это не удается, потому что имена некоторых классов изменились.Unpickling классы из Python 3 в Python 2

Предположим, у нас есть код, называемый следующим образом.

Sender

pickle.dumps(obj,2) 

Приемник

pickle.loads(atom) 

Чтобы дать конкретный случай, если obj={}, то выдаваемая ошибка является:

ImportError: No module named builtins

Это потому, что Python 2 использует __builtin__ вместо ,

Вопрос - это лучший способ исправить эту проблему.

ответ

13

Эта проблема Python issue 3675. Эта ошибка фактически исправлена ​​в Python 3.11.

Если мы импортируем:

from lib2to3.fixes.fix_imports import 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.

Это должно решить проблему.

Смежные вопросы