<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Mundo Geek &#187; serializacion</title>
	<atom:link href="http://mundogeek.net/etiqueta/serializacion/feed/" rel="self" type="application/rss+xml" />
	<link>http://mundogeek.net</link>
	<description>Mundo geek, bitácora sobre todo lo geek: software, gadgets, tecnología, internet, ...</description>
	<lastBuildDate>Fri, 25 May 2012 14:51:34 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Python: Serialización de objetos</title>
		<link>http://mundogeek.net/archivos/2008/05/20/python-serializacion-de-objetos/</link>
		<comments>http://mundogeek.net/archivos/2008/05/20/python-serializacion-de-objetos/#comments</comments>
		<pubDate>Tue, 20 May 2008 09:00:46 +0000</pubDate>
		<dc:creator>Zootropo</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[pickle]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[serializacion]]></category>
		<category><![CDATA[shelve]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://mundogeek.net/archivos/2008/05/19/python-serializacion-de-objetos/</guid>
		<description><![CDATA[Algunas veces tenemos la necesidad de guardar un objeto a disco para poder recuperarlo más tarde, o puede que nos sea necesario mandar un objeto a través de la red, a otro programa en Python ejecutándose en otra máquina. Al proceso de transformar el estado de un objeto en un formato que se pueda almacenar, [...]]]></description>
			<content:encoded><![CDATA[<p>Algunas veces tenemos la necesidad de guardar un objeto a disco para poder recuperarlo más tarde, o puede que nos sea necesario mandar un objeto a través de la red, a otro programa en Python ejecutándose en otra máquina.</p>
<p>Al proceso de transformar el estado de un objeto en un formato que se pueda almacenar, recuperar y transportar se le conoce con el nombre de serialización o <em>marshalling</em>.</p>
<p>En Python tenemos varios módulos que nos facilitan esta tarea, como <code>marshal</code>, <code>pickle</code>, <code>cPickle</code> y <code>shelve</code>.</p>
<p><span id="more-1517"></span></p>
<p>El módulo <code>marshal</code> es el más básico y el más primitivo de los tres, y es que, de hecho, su propósito principal y su razón de ser no es el de serializar objetos, sino trabajar con bytecode Python (archivos .pyc).</p>
<p><code>marshal</code> sólo permite serializar objetos simples (la mayoría de los tipos incluidos por defecto en Python), y no proporciona ningún tipo de mecanismo de seguridad ni comprobaciones frente a datos corruptos o mal formateados. Es más, el formato utilizado para guardar el bytecode (y por tanto el formato utilizado para guardar los objetos con <code>marshal</code>) puede cambiar entre versiones, por lo que no es adecuado para almacenar datos de larga duración.</p>
<p><code>pickle</code>, por su parte, permite serializar casi cualquier objeto (objetos de tipos definidos por el usuario, colecciones que contienen colecciones, etc) y cuenta con algunos mecanismos de seguridad básicos.  Sin embargo, al ser más complejo que marshal, y, sobre todo, al estar escrito en Python en lugar de en C, como <code>marshal</code>, también es mucho más lento.</p>
<p>La solución, si la velocidad de la serialización es importante para nuestra aplicación, es utilizar <code>cPickle</code>, que no es más que es una implementación en C de <code>pickle</code>. <code>cPickle</code> es hasta 1000 veces más rápido que <code>pickle</code>, y prácticamente igual de rápido que <code>marshal</code>.</p>
<p>Si intentamos importar <code>cPickle</code> y se produce un error por algún motivo, se lanzará una excepción de tipo <code>ImportError</code>. Para utilizar <code>cPickle</code> si está disponible y <code>pickle</code> en caso contrario, podríamos usar un código similar al siguiente:</p>
<pre name="code" class="python">try:
    import cPickle as pickle
except ImportError:
    import pickle</pre>
<p><code>as</code> en un <code>import</code> sirve para importar el elemento seleccionado utilizando otro nombre indicado, en lugar de su nombre.</p>
<p>La forma más sencilla de serializar un objeto usando <code>pickle</code> es mediante una llamada a la función <code>dump</code> pasando como argumento el nombre del objeto a serializar y un objeto archivo en el que guardarlo (o cualquier otro tipo de objeto similar a un archivo, siempre que ofrezca métodos <code>read</code>, <code>realine</code> y <code>write</code>).</p>
<pre name="code" class="python">try:
    import cPickle as pickle
except ImportError:
    import pickle

fichero = file("datos.dat", "w")
animales = ["piton", "mono", "camello"]

pickle.dump(animales, fichero)

fichero.close()</pre>
<p>La función <code>dump</code> también tiene un parámetro opcional <code>protocol</code> que indica el protocolo a utilizar al guardar. Por defecto su valor es 0, que utiliza formato texto y es el menos eficiente. El protocolo 1 es más eficiente que el 0, pero menos que el 2. Tanto el protocolo 1 como el 2 utilizan un formato binario para guardar los datos.</p>
<pre name="code" class="python">try:
    import cPickle as pickle
except ImportError:
    import pickle

fichero = file("datos.dat", "w")
animales = ["piton", "mono", "camello"]

pickle.dump(animales, fichero, 2)

fichero.close()</pre>
<p>Para volver a cargar un objeto serializado se utiliza la función <code>load</code>, a la que se le pasa el archivo en el que se guardó. </p>
<pre name="code" class="python">try:
    import cPickle as pickle
except ImportError:
    import pickle

fichero = file("datos.dat", "w")
animales = ["piton", "mono", "camello"]

pickle.dump(animales, fichero)

fichero.close()

fichero = file("datos.dat")

animales2 = pickle.load(fichero)
print animales2</pre>
<p>Supongamos ahora que queremos almacenar un par de listas en un fichero. Esto sería tan sencillo como llamar una vez a <code>dump</code> por cada lista, y llamar después una vez a <code>load</code> por cada lista.</p>
<pre name="code" class="python">fichero = file("datos.dat", "w")
animales = ["piton", "mono", "camello"]
lenguajes = ["python", "mono", "perl"]

pickle.dump(animales, fichero)
pickle.dump(lenguajes, fichero)

fichero = file("datos.dat")

animales2 = pickle.load(fichero)
lenguajes2 = pickle.load(fichero)
print animales2
print lenguajes2</pre>
<p>Pero, ¿y si hubiéramos guardado 30 objetos y quisiéramos acceder al último de ellos? ¿o si no recordáramos en qué posición lo habíamos guardado? El módulo <code>shelve</code> extiende <code>pickle</code> / <code>cPickle</code> para proporcionar una forma de realizar la serialización más clara y sencilla, en la que podemos acceder a la versión serializada de un objeto mediante una cadena asociada, a través de una estructura parecida a un diccionario.</p>
<p>La única función que necesitamos conocer del módulo <code>shelve</code> es <code>open</code>, que cuenta con un parámetro <code>filename</code> mediante el que indicar la ruta a un archivo en el que guardar los objetos (en realidad se puede crear más de un archivo, con nombres basados en <code>filename</code>, pero esto es transparente al usuario).</p>
<p>La función <code>open</code> también cuenta con un parámetro opcional <code>protocol</code>, con el que especificar el protocolo que queremos que utilice <code>pickle</code> por debajo.</p>
<p>Como resultado de la llamada a <code>open</code> obtenemos un objeto <code>Shelf</code>, con el que podemos trabajar como si de un diccionario normal se tratase (a excepción de que las claves sólo pueden ser cadenas) para almacenar y recuperar nuestros objetos.</p>
<p>Como un diccionaro cualquiera la clase <code>Shelf</code> cuenta con métodos <code>get</code>, <code>has_key</code>, <code>items</code>, <code>keys</code>, <code>values</code>, &#8230;</p>
<p>Una vez hemos terminado de trabajar con el objeto <code>Shelf</code>, lo cerramos usando el método <code>close</code>. </p>
<pre name="code" class="python">import shelve

animales = ["piton", "mono", "camello"]
lenguajes = ["python", "mono", "perl"]

shelf = shelve.open("datos.dat")
shelf["primera"] = animales
shelf["segunda"] = lenguajes

print shelf["segunda"]

shelf.close()</pre>
<link type="text/css" rel="stylesheet" href="http://mundogeek.net/sh/css/SyntaxHighlighter.css"></link>
<script language="javascript" src="http://mundogeek.net/sh/js/shCore.js"></script><br />
<script language="javascript" src="http://mundogeek.net/sh/js/shBrushPython.js"></script><br />
<script language="javascript">dp.SyntaxHighlighter.ClipboardSwf = 'http://mundogeek.net/sh//flash/clipboard.swf';
dp.SyntaxHighlighter.HighlightAll('code');</script></p>
]]></content:encoded>
			<wfw:commentRss>http://mundogeek.net/archivos/2008/05/20/python-serializacion-de-objetos/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
	</channel>
</rss>

