<?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; ficheros</title>
	<atom:link href="http://mundogeek.net/etiqueta/ficheros/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: Entrada / Salida. Ficheros</title>
		<link>http://mundogeek.net/archivos/2008/04/02/python-entrada-salida-ficheros/</link>
		<comments>http://mundogeek.net/archivos/2008/04/02/python-entrada-salida-ficheros/#comments</comments>
		<pubDate>Wed, 02 Apr 2008 09:00:09 +0000</pubDate>
		<dc:creator>Zootropo</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[entrada]]></category>
		<category><![CDATA[ficheros]]></category>
		<category><![CDATA[programacion]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[salida]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://mundogeek.net/?p=1435</guid>
		<description><![CDATA[Nuestros programas serían de muy poca utilidad si no fueran capaces de interaccionar con el usuario. En capítulos anteriores vimos, de pasada, el uso de la palabra clave print para mostrar mensajes en pantalla. En esta lección, además de describir más detalladamente del uso de print para mostrar mensajes al usuario, aprenderemos a utilizar las [...]]]></description>
			<content:encoded><![CDATA[<p>Nuestros programas serían de muy poca utilidad si no fueran capaces de interaccionar con el usuario. En capítulos anteriores vimos, de pasada, el uso de la palabra clave <code>print</code> para mostrar mensajes en pantalla.</p>
<p>En esta lección, además de describir más detalladamente del uso de <code>print</code> para mostrar mensajes al usuario, aprenderemos a utilizar las funciones <code>input</code> y <code>raw_input</code> para pedir información, así como los argumentos de línea de comandos y, por último, la entrada/salida de ficheros.<br />
<span id="more-1435"></span></p>
<h2>Entrada estándar</h2>
<p>La forma más sencilla de obtener información por parte del usuario es mediante la función <code>raw_input</code>. Esta función toma como parámetro una cadena a usar como prompt (es decir, como texto a mostrar al usuario pidiendo la entrada) y devuelve una cadena con los caracteres introducidos por el usuario hasta que pulsó la tecla Enter. Veamos un pequeño ejemplo:</p>
<pre class="code">nombre = raw_input(<span class="Normal">&quot;</span><span class="String">Como te llamas? </span><span class="Normal">&quot;</span>)
<span class="pythonStatement">print</span> <span class="Normal">&quot;</span><span class="String">Encantado, </span><span class="Normal">&quot;</span> + nombre</pre>
<p>Si necesitáramos un entero como entrada en lugar de una cadena, por ejemplo, podríamos utilizar el constructor de <code>int</code> para convertir la cadena a entero, aunque sería conveniente tener en cuenta que puede lanzarse una excepción si lo que introduce el usuario no es un número.</p>
<pre class="code"><span class="pythonStatement">try</span>:
    edad = raw_input(<span class="Normal">&quot;</span><span class="String">Cuantos anyos tienes? </span><span class="Normal">&quot;</span>)
    dias = int(edad) * 365
    <span class="pythonStatement">print</span> <span class="Normal">&quot;</span><span class="String">Has vivido </span><span class="Normal">&quot;</span> + str(dias) + <span class="Normal">&quot;</span> <span class="String">dias</span><span class="Normal">&quot;</span>
<span class="pythonStatement">except</span> ValueError:
    <span class="pythonStatement">print</span> <span class="Normal">&quot;</span><span class="String">Eso no es un numero</span><span class="Normal">&quot;</span></pre>
<p>La función <code>input</code> es un poco más complicada. Lo que hace esta función es utilizar <code>raw_input</code> para leer una cadena de la entrada estándar, y después pasa a evaluarla como si de código Python se tratara; por lo tanto <code>input</code> debería tratarse con sumo cuidado.</p>
<h2>Parámetros de línea de comando</h2>
<p>Además del uso de <code>input</code> y <code>raw_input</code> el programador Python cuenta con otros métodos para obtener datos del usuario. Uno de ellos es el uso de parámetros a la hora de llamar al programa en la línea de comandos. Por ejemplo:</p>
<p class="code">python editor.py hola.txt</p>
<p>En este caso hola.txt sería el parámetro, al que se puede acceder a través de la lista <code>sys.argv</code>, aunque, como es de suponer, antes de poder utilizar dicha variable debemos importar el módulo <code>sys</code>. <code>sys.argv[0]</code> contiene siempre el nombre del programa tal como lo ha ejecutado el usuario, <code>sys.argv[1]</code>, si existe, sería el primer parámetro; <code>sys.argv[2]</code> el segundo, y así sucesivamente.</p>
<pre class="code"><span class="pythonPrecondit">import</span> sys

<span class="pythonConditional">if</span>(len(sys.argv) &gt; 1):
    <span class="pythonStatement">print</span> <span class="Normal">&quot;</span><span class="String">Abriendo</span> <span class="Normal">&quot;</span> + sys.argv[1]
<span class="pythonConditional">else</span>:
    <span class="pythonStatement">print</span> <span class="Normal">&quot;</span><span class="String">Debes indicar el nombre del archivo</span><span class="Normal">&quot;</span></pre>
<p>Existen módulos, como <code>optparse</code>, que facilitan el trabajo con los argumentos de la línea de comandos, pero explicar su uso queda fuera del objetivo de esta lección.</p>
<h2>Salida estándar</h2>
<p>La forma más sencilla de mostrar algo en la salida estándar es mediante el uso de la sentencia <code>print</code>, como hemos visto multitud de veces en ejemplos anteriores. En su forma más básica a la palabra clave <code>print</code> le sigue una cadena, que se mostrará en la salida estándar al ejecutarse el estamento.</p>
<p class="code">&gt;&gt;&gt; print &#8220;Hola mundo&#8221;<br />
Hola mundo</p>
<p>Después de imprimir la cadena pasada como parámetro el puntero se sitúa en la siguiente línea de la pantalla, por lo que el <code>print</code> de Python funciona igual que el <code>println</code> de Java.</p>
<p>En algunas funciones equivalentes de otros lenguajes de programación es necesario añadir un carácter de nueva línea para indicar explícitamente que queremos pasar a la siguiente línea. Este es el caso de la función <code>printf</code> de C o la propia función <code>print</code> de Java.</p>
<p>Ya explicamos el uso de estos caracteres especiales en su día durante la explicación del tipo cadena de la lección <a href="http://mundogeek.net/archivos/2008/01/17/python-tipos-basicos/" title="Python: Tipos básicos">Python: Tipos básicos</a>. La siguiente sentencia, por ejemplo, imprimiría la palabra &#8220;Hola&#8221;, seguida de un renglón vacío (dos caracteres de nueva línea, &#8216;\n&#8217;), y a continuación la palabra &#8220;mundo&#8221; indentada (un carácter tabulador, &#8216;\t&#8217;).</p>
<pre class="code"><span class="pythonStatement">print</span> <span class="Normal">&quot;</span><span class="String">Hola</span><span class="pythonEscape">\n\n\t</span><span class="String">mundo</span><span class="Normal">&quot;</span></pre>
<p>Para que la siguiente impresión se realizara en la misma línea tendríamos que colocar una coma al final de la sentencia. Comparemos el resultado de este código:</p>
<p class="code">&gt;&gt;&gt; for i in range(3):<br />
&gt;&gt;&gt; &#8230;print i,<br />
0 1 2</p>
<p>Con el de este otro, en el que no utiliza una coma al final de la sentencia:</p>
<p class="code">&gt;&gt;&gt; for i in range(3):<br />
&gt;&gt;&gt; &#8230;print i<br />
0<br />
1<br />
2</p>
<p>Este mecanismo de colocar una coma al final de la sentencia funciona debido a que es el símbolo que se utiliza para separar cadenas que queramos imprimir en la misma línea.</p>
<p class="code">&gt;&gt;&gt; print &#8220;Hola&#8221;, &#8220;mundo&#8221;<br />
Hola mundo</p>
<p>Esto se diferencia del uso del operador &#8216;+&#8217; para concatenar las cadenas en que al utilizar las comas <code>print</code> introduce automáticamente un espacio para separar cada una de las cadenas. Este no es el caso al utilizar el operador +, ya que lo que le llega a <code>print</code> es un solo argumento: una cadena ya concatenada.</p>
<p class="code">&gt;&gt;&gt; print &#8220;Hola&#8221; + &#8220;mundo&#8221;<br />
Holamundo</p>
<p>Además, al utilizar el operador + tendríamos que convertir antes cada argumento en una cadena de no serlo ya, ya que no es posible concatenar cadenas y otros tipos, mientras que al usar el primer método no es necesaria la conversión.</p>
<p class="code">&gt;&gt;&gt; print &#8220;Cuesta&#8221;, 3, &#8220;euros&#8221;<br />
Cuesta 3 euros<br />
&gt;&gt;&gt; print &#8220;Cuesta&#8221; + 3 + &#8220;euros&#8221;<br />
&lt;type &#8216;exceptions.TypeError&#8217;&gt;: cannot concatenate &#8216;str&#8217; and &#8216;int&#8217; objects</p>
<p>La sentencia <code>print</code>, o más bien las cadenas que imprime, permiten también utilizar técnicas avanzadas de formateo, de forma similar al <code>sprintf</code> de C. Veamos un ejemplo bastante simple:</p>
<pre class="code"><span class="pythonStatement">print</span> <span class="Normal">&quot;</span><span class="String">Hola %s</span><span class="Normal">&quot;</span> % <span class="Normal">&quot;</span><span class="String">mundo</span><span class="Normal">&quot;</span>
<span class="pythonStatement">print</span> <span class="Normal">&quot;</span><span class="String">%s %s</span><span class="Normal">&quot;</span> % (<span class="Normal">&quot;</span><span class="String">Hola</span><span class="Normal">&quot;</span>, <span class="Normal">&quot;</span><span class="String">mundo</span><span class="Normal">&quot;</span>)</pre>
<p>Lo que hace la primera línea es introducir los valores a la derecha del símbolo &#8216;%&#8217; (la cadena &#8220;mundo&#8221;) en las posiciones indicadas por los <em>especificadores de conversión</em> de la cadena a la izquierda del símbolo &#8216;%&#8217;, tras convertirlos al tipo adecuado.</p>
<p>En el segundo ejemplo, vemos cómo se puede pasar más de un valor a sustituir, por medio de una tupla.</p>
<p>En este ejemplo sólo tenemos un especificador de conversión: &#8216;%s&#8217;.</p>
<p>Los especificadores más sencillos están formados por el símbolo &#8216;%&#8217; seguido de una letra que indica el tipo con el que formatear el valor. Por ejemplo:</p>
<table border="1">
<tr>
<td><b>Especificador</b></td>
<td><b>Formato</b></td>
</tr>
<tr>
<td>%s</td>
<td>Cadena</td>
</tr>
<tr>
<td>%d</td>
<td>Entero</td>
</tr>
<tr>
<td>%o</td>
<td>Octal</td>
</tr>
<tr>
<td>%x</td>
<td>Hexadecimal</td>
</tr>
<tr>
<td>%f</td>
<td>Real</td>
</tr>
</table>
<p>Se puede introducir un número entre el &#8216;%&#8217; y el carácter que indica el tipo al que formatear, indicando el número mínimo de caracteres que queremos que ocupe la cadena. Si el tamaño de la cadena resultante es menor que este número, se añadirán espacios a la izquierda de la cadena. En el caso de que el número sea negativo, ocurrirá exactamente lo mismo, sólo que los espacios se añadirán a la derecha de la cadena.</p>
<p class="code">&gt;&gt;&gt; print &#8220;%10s mundo&#8221; % &#8220;Hola&#8221;<br />
______Hola mundo<br />
&gt;&gt;&gt; print &#8220;%-10s mundo&#8221; % &#8220;Hola&#8221;<br />
Hola_______mundo</p>
<p>En el caso de los reales es posible indicar la precisión a utilizar precediendo la &#8216;f&#8217; de un punto seguido del número de decimales que queremos mostrar:</p>
<p class="code">&gt;&gt;&gt; from math import pi<br />
&gt;&gt;&gt; print &#8220;%.4f&#8221; % pi<br />
3.1416</p>
<p>La misma sintaxis se puede utilizar para indicar el número de caracteres de la cadena que queremos mostrar</p>
<p class="code">&gt;&gt;&gt; print &#8220;%.4s&#8221; % &#8220;hola mundo&#8221;<br />
hola</p>
<h2>Archivos</h2>
<p>Los ficheros en Python son objetos de tipo <code>file</code> creados mediante la función <code>open</code> (abrir). Esta función toma como parámetros una cadena con la ruta al fichero a abrir, que puede ser relativa o absoluta; una cadena opcional indicando el modo de acceso (si no se especifica se accede en modo lectura) y, por último, un entero opcional para especificar un tamaño de buffer distinto del utilizado por defecto.</p>
<p>El modo de acceso puede ser cualquier combinación lógica de los siguientes modos:</p>
<ul>
<li>&#8216;r&#8217;: read, lectura. Abre el archivo en modo lectura. El archivo tiene que existir previamente, en caso contrario se lanzará una excepción de tipo <code>IOError</code>.</li>
<li>&#8216;w&#8217;: write, escritura. Abre el archivo en modo escritura. Si el archivo no existe se crea. Si existe, sobreescribe el contenido.</li>
<li>&#8216;a&#8217;: append, añadir. Abre el archivo en modo escritura. Se diferencia del modo &#8216;w&#8217; en que en este caso no se sobreescribe el contenido del archivo, sino que se comienza a escribir al final del archivo.</li>
<li>&#8216;b&#8217;: binary, binario.</li>
<li>&#8216;+&#8217;: permite lectura y escritura simultáneas.</li>
<li>&#8216;U&#8217;: universal newline, saltos de línea universales. Permite trabajar con archivos que tengan un formato para los saltos de línea que no coincide con el de la plataforma actual (en Windows se utiliza el caracter CR LF, en Unix LF y en Mac OS CR).</li>
</ul>
<pre class="code">f = open(<span class="Normal">&quot;</span><span class="String">archivo.txt</span><span class="Normal">&quot;</span>, <span class="Normal">&quot;</span><span class="String">w</span><span class="Normal">&quot;</span>)</pre>
<p>Tras crear el objeto que representa nuestro archivo mediante la función <code>open</code> podremos realizar las operaciones de lectura/escritura pertinentes utilizando los métodos del objeto que veremos en las siguientes secciones.</p>
<p>Una vez terminemos de trabajar con el archivo debemos cerrarlo utilizando el método <code>close</code>.</p>
<h3>Lectura de archivos</h3>
<p>Para la lectura de archivos se utilizan los métodos <code>read</code>, <code>readline</code> y <code>realines</code>. </p>
<p>El método <code>read</code> devuelve una cadena con el contenido del archivo o bien el contenido de los primeros n bytes, si se especifica el tamaño máximo a leer.</p>
<pre class="code">completo = f.read()

parte = f2.read(512)</pre>
<p>El método <code>readline</code> sirve para leer las líneas del fichero una por una. Es decir, cada vez que se llama a este método, se devuelve el contenido del archivo desde el puntero hasta que se encuentra un carácter de nueva línea, incluyendo este carácter.</p>
<pre class="code"><span class="pythonRepeat">while</span> True:
      linea = f.readline()
      <span class="pythonConditional">if</span> <span class="pythonOperator">not</span> linea: <span class="pythonStatement">break</span>
      <span class="pythonStatement">print</span> line</pre>
<p>Por último, <code>readlines</code>, funciona leyendo todas las líneas del archivo y devolviendo una lista con las líneas leídas. </p>
<h3>Escritura de archivos</h3>
<p>Para la escritura de archivos se utilizan los método <code>write</code> y <code>writelines</code>. Mientras el primero funciona escribiendo en el archivo una cadena de texto que toma como parámetro, el segundo toma como parámetro una lista de cadenas de texto indicando las líneas que queremos escribir en el fichero. </p>
<h3>Mover el puntero de lectura/escritura en ficheros</h3>
<p>Hay situaciones en las que nos puede interesar mover el puntero de lectura/escritura a una posición determinada del archivo. Por ejemplo si queremos empezar a escribir en una posición determinada y no al final o al principio del archivo.</p>
<p>Para esto se utiliza el método <code>seek</code> que toma como parámetro un número positivo o negativo a utilizar como desplazamiento. También es posible utilizar un segundo parámetro para indicar desde dónde queremos que se haga el desplazamiento: 0 indicará que el desplazamiento se refiere al principio del fichero (comportamiento por defecto), 1 se refiere a la posición actual, y 2, al final del fichero.</p>
<p>Para determinar la posición en la que se encuentra actualmente el puntero se utiliza el método <code>tell</code>, que devuelve un entero indicando la distancia en bytes desde el principio del fichero.</p>
]]></content:encoded>
			<wfw:commentRss>http://mundogeek.net/archivos/2008/04/02/python-entrada-salida-ficheros/feed/</wfw:commentRss>
		<slash:comments>35</slash:comments>
		</item>
	</channel>
</rss>

