2009-09-06 12 views
5

Si una clase de Python 3 se escanea utilizando el protocolo 2, se supone que funciona en Python 2, pero lamentablemente esto falla porque los nombres de algunas clases han cambiado.Eliminación de clases de Python 3 en Python 2

Supongamos que tenemos un código llamado de la siguiente manera.

remitente

pickle.dumps(obj,2) 

Receptor

pickle.loads(atom) 

para dar un caso específico, si obj={}, entonces el error dado es:

ImportError: No module named builtins

Esto es porque Python 2 utiliza __builtin__ en vez .

La pregunta es la mejor manera de solucionar este problema.

Respuesta

13

Este problema es Python issue 3675. Este error está realmente arreglado en Python 3.11.

Si nos importan:

from lib2to3.fixes.fix_imports import MAPPING 

MAPEO mapas Python 2 nombres a Python 3 nombres. Queremos esto a la inversa.

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

Nos puede anular el Unpickler y cargas

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

Luego llamamos a este lugar de cargas pickle.loads.

Esto debería resolver el problema.