2009-03-20 16 views
9

¿El defaultnoun no se convirtió en compatible a partir de Python 2.6? Los siguientes obras bajo 2.5, falla bajo 2.6 con "ValueError: objeto unmarshallable" en OS X 1.5.6, Python-2.6.1-macosx2008-12-06.dmg de python.org:Python: defaultdict se convirtió en un objeto inmarshallable en 2.6?

from collections import defaultdict 
import marshal 
dd = defaultdict(list) 
marshal.dump(dd, file('/tmp/junk.bin','wb')) 

Respuesta

11

Marshal was deliberately changed to not support subclasses of built-in types. Nunca se suponía que Marshal manejara los valores predeterminados, pero sucedió porque son una subclase de dict. Marshal is not a general "persistence" module; only None, integers, long integers, floating point numbers, strings, Unicode objects, tuples, lists, sets, dictionaries, and code objects are supported.

Python 2.5:

>>> marshal.dumps(defaultdict(list)) 
'{0' 
>>> marshal.dumps(dict()) 
'{0' 

Si por alguna razón usted realmente quiere formar un defaultdict se puede convertir a un diccionario en primer lugar, pero las probabilidades son que usted debe utilizar un mecanismo de serialización diferente, como pickling.

+0

Gracias Miles. El problema es que hay una diferencia de rendimiento muy significativa entre el decapado y el cálculo de referencias: en el tamaño de datos con el que estoy trabajando asciende a unas pocas horas por cada ejecución. Supongo que me quedaré con 2.5 o convertiré a un dict antes de ordenar. – Parand

+0

¿Estás usando cPickle, con HIGHEST_PROTOCOL? – Miles

7

problemas de rendimiento wrt .. codifican una lista de ~ 600000 dicts, cada uno con 4 claves/valores, uno de los valores tiene una lista (alrededor de 1-3 longitud) de 2 clave dicts/Val:

In [27]: timeit(cjson.encode, data) 
4.93589496613 

In [28]: timeit(cPickle.dumps, data, -1) 
141.412974119 

In [30]: timeit(marshal.dumps, data, marshal.version) 
1.13546991348 
+1

gc.disable(); timeit (cPickle.dumps, ...); gc.enable() reduce el tiempo a alrededor de 14 segundos, lo que podría ser una mejora bastante buena. –

+0

Aquí se ejecutaron puntos de referencia similares y Marshal es aproximadamente 15 veces más rápido que cPickle para diccionarios y listas en mi BeagleBoard. Nunca pensé que ese sería el caso. Gracias @dsvensson por la iluminación libre. –