Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Python
http://python.org.ar/pyar/Tutorial
Septiembre 2009
Esta documentaci�n est� cubierta por la Licencia PSF para Python 2.6.2,
quebasicamente permite que use, copies, modifiques y distribuyas este contenido.
Para un mayor detalle: http://www.python.org/doc/2.6.2/copyright.html
Contenido
Introducci�n 7
Abriendo tu apetito 8
Usando el int�rprete de Python 10
Invocando al int�rprete 10
Pasaje de argumentos 11
Modo interactivo 11
El int�rprete y su entorno 12
Manejo de errores 12
Programas ejecutables de Python 12
Codificaci�n del c�digo fuente 13
El archivo de inicio interactivo 13
La sentencia if 28
La sentencia for 28
La funci�n range() 29
La sentencia pass 30
Definiendo funciones 31
Estructuras de datos 40
M�dulos 52
Entrada y salida 63
Errores y excepciones 71
Errores de sintaxis 71
Excepciones 71
Manejando excepciones 72
Levantando excepciones 75
Excepciones definidas por el usuario 75
Definiendo acciones de limpieza 77
Acciones predefinidas de limpieza 78
Clases 79
Unas palabras sobre nombres y objetos 79
Alcances y espacios de nombres en Python 79
Un primer vistazo a las clases 81
Sintaxis de definici�n de clases 81
Objetos clase 82
Objetos instancia 83
Objetos m�todo 84
Algunas observaciones 85
Herencia 86
Herencia m�ltiple 87
Variables privadas 88
Cambalache 89
Las excepciones tambi�n son clases 89
Iteradores 90
Generadores 92
Expresiones generadoras 92
Este tutorial no pretende ser exhaustivo ni tratar cada una de las caracter�sticas,
o siquiera las
caracter�sticas m�s usadas. En cambio, introduce la mayor�a de las caracter�sticas
m�s notables de
Python, y te dar� una buena idea del gusto y estilo del lenguaje. Luego de leerlo,
ser�s capaz de leer y
escribir m�dulos y programas en Python, y estar�s listo para aprender m�s de los
variados m�dulos de la
biblioteca de Python descriptos en la Referencia de la Biblioteca de Python.
7
Abriendo tu apetito
Python permite escribir programas compactos y legibles. Los programas en Python son
t�picamente m�s
cortos que sus programas equivalentes en C, C++ o Java por varios motivos:
� los tipos de datos de alto nivel permiten expresar operaciones complejas en una
sola instrucci�n
� la agrupaci�n de instrucciones se hace por snagr�a en vez de llaves de apertura y
cierre
8
� no es necesario declarar variables ni argumentos.
Python es extensible: si ya sabes programar en C es f�cil agregar una nueva funci�n
o m�dulo al
int�rprete, ya sea para realizar operaciones cr�ticas a velocidad m�xima, o para
enlazar programas Python
con bibliotecas que tal vez s�lo est�n disponibles en forma binaria (por ejemplo
bibliotecas gr�ficas
espec�ficas de un fabricante). Una vez que est�s realmente entusiasmado, pod�s
enlazar el int�rprete
Python en una aplicaci�n hecha en C y usarlo como lenguaje de extensi�n o de
comando para esa
aplicaci�n.
Ahora que ya est�s emocionado con Python, querr�s verlo en m�s detalle. Como la
mejor forma de
aprender un lenguaje es usarlo, el tutorial te invita a que juegues con el
int�rprete de Python a medida que
vas leyendo.
9
Usando el int�rprete de Python
Invocando al int�rprete
python
set path=%path%;C:\python26
Se puede salir del int�rprete con estado de salida cero ingresando el car�cter de
fin de archivo
(Control-D en Unix, Control-Z en Windows) en el prompt primario. Si esto no
funciona, se puede salir
del int�rprete ingresando: import sys; sys.exit().
Las caracter�sticas para editar l�neas del int�rprete no son muy sofisticadas. En
Unix, quien instale el
int�rprete tendr� habilitado el soporte para la biblioteca GNU readlines, que a�ade
una edici�n interactiva
m�s elaborada e historia. Tal vez la forma m�s r�pida de detectar si las
caracter�sticas de edici�n est�n
presentes es ingresar Control-P en el primer prompt de Python que aparezca. Si se
escucha un beep, las
caracter�sticas est�n presentes; ver Ap�ndice tut-interacting para una introducci�n
a las teclas. Si no pasa
nada, o si aparece ^P, estas caracter�sticas no est�n disponibles; solo vas a poder
usar backspace para
borrar los caracteres de la l�nea actual.
Algunos m�dulos de Python son tambi�n �tiles como scripts. Pueden invocarse usando
python -m
module [arg] ..., que ejecuta el c�digo de module como si se hubiese ingresado su
nombre completo
en la l�nea de comandos.
10
Not� que existe una diferencia entre python file y python <file. En el �ltimo caso,
la entrada
solicitada por el programa, como en llamadas a input() y raw_input(), son
satisfechas desde file. Ya
que este archivo ya fue le�do hasta el final por el analizador antes de que el
programa empiece su
ejecuci�n, se encontrar� el fin de archivo enseguida. En el primer caso (lo que
usualmente vas a querer)
son satisfechas por cualquier archivo o dispositivo que est� conectado a la entrada
est�ndar del int�rprete
de Python.
Cuando se usa un script, a veces es �til correr primero el script y luego entrar al
modo interactivo. Esto se
puede hacer pas�ndole la opci�n -i antes del nombre del script. (Esto no funciona
si el script es le�do
desde la entrada est�ndar, por la misma raz�n explicada en el p�rrafo anterior).
Pasaje de argumentos
Cuando son conocidos por el int�rprete, el nombre del script y los argumentos
adicionales son entonces
pasados al script en la variable sys.argv, una lista de cadenas de texto. Su
longitud es al menos uno;
cuando ning�n script o argumentos son pasados, sys.argv[0] es una cadena vac�a.
Cuando se pasa
el nombre del script con '-' (lo que significa la entrada est�ndar), sys.argv[0]
vale '-'. Cuando se
usa -c command, sys.argv[0] vale '-c'. Cuando se usa -m module, sys.argv[0] toma el
valor del
nombre completo del m�dulo. Las opciones encontradas luego de -c command o -m
module no son
consumidas por el procesador de opciones de Python pero de todas formas almacenadas
en sys.argv
para ser manejadas por el comando o m�dulo.
Modo interactivo
Se dice que estamos usando el int�rprete en modo interactivo, cuando los comandos
son le�dos desde
una terminal. En este modo espera el siguiente comando con el prompt primario,
usualmente tres signos
mayor-que (>>>); para las l�neas de continuaci�n espera con el prompt secundario,
por defecto tres
puntos (...). Antes de mostrar el prompt primario, el int�rprete muestra un mensaje
de bienvenida
reportando su n�mero de versi�n y una nota de copyright:
python
Python 2.6 (#1, Feb 28 2007, 00:02:06)
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> el_mundo_es_plano = 1
>>> if el_mundo_es_plano:
... print u"�Ten� cuidado de no caerte!"
...
11
El int�rprete y su entorno
Manejo de errores
En los sistemas Unix y tipo BSD, los programas Python pueden convertirse
directamente en ejecutables,
como programas del int�rprete de comandos, poniendo la linea:
#! /usr/bin/env python
$ chmod +x myscript.py
12
Codificaci�n del c�digo fuente
Con esa declaraci�n, todos los caracteres en el archivo fuente ser�n traducidos
utilizando la codificaci�n
encoding, y ser� posible escribir directamente cadenas de texto literales Unicode
en la codificaci�n
seleccionada. La lista de posibles codificaciones se puede encontrar en la
Referencia de la Biblioteca de
Python, en la secci�n sobre codecs.
moneda = u"�"
print ord(moneda)
Si tu editor tiene soporte para guardar archivos como UTF-8 con marca de orden de
byte UTF-8 (tambi�n
conocida como BOM), pod�s usar eso en lugar de la declaraci�n de codificaci�n. IDLE
lo soporta si se
activa Options/General/Default Source Encoding/UTF-8. Not� que esto no funciona en
versiones antiguas de Python (2.2 y anteriores), ni por el sistema operativo en
scripts con la l�nea con #!
(solo usado en sistemas Unix).
Usando UTF-8 (ya sea mediante BOM o la declaraci�n de codificaci�n), los caracteres
de la mayor�a de
los idiomas del mundo pueden ser usados simult�neamente en cadenas de texto o
comentarios. No se
soporta usar caracteres no-ASCII en identificadores. Para mostrar todos estos
caracteres de forma
apropiada, tu editor debe reconocer que el archivo es UTF-8, y debe usar una
tipograf�a que soporte todos
los caracteres del archivo.
Cuando us�s Python en forma interactiva, suele ser �til que algunos comandos
est�ndar se ejecuten cada
vez que el int�rprete se inicia. Pod�s hacer esto configurando la variable de
entorno PYTHONSTARTUP
con el nombre de un archivo que contenga tus comandos de inicio. Esto es similar al
archivo .profile
en los int�rpretes de comandos de Unix.
Este archivo es solo le�do en las sesiones interactivas del int�rprete, no cuando
Python lee comandos de
un script ni cuando file:/dev/tty se explicita como una fuente de comandos (que de
otro modo se comporta
como una sesi�n interactiva). Se ejecuta en el mismo espacio de nombres en el que
los comandos
interactivos se ejecutan, entonces los objetos que define o importa pueden ser
usados sin cualificaciones
en la sesi�n interactiva. En este archivo tambi�n pod�s cambiar los prompts sys.ps1
y sys.ps2.
13
Si quer�s leer un archivo de inicio adicional desde el directorio actual, pod�s
programarlo en el archivo de
inicio global usando algo como if os.path.isfile('.pythonrc.py'):
execfile('.pythonrc.py'). Si quer�s usar el archivo de inicio en un script, ten�s
que hacer lo
siguiente en forma expl�cita en el script:
import os
nombrearchivo = os.environ.get('PYTHONSTARTUP')
14
Una introducci�n informal a Python
Algunos ejemplos:
SPAM = 1
# y este es el segundo comentario
# ... y ahora un tercero!
N�meros
El int�rprete act�a como una simple calculadora; pod�s ingrsar una expresi�n y este
escribir� los valores.
La sintaxis es sencilla: los operadores +, -, * y / funcionan como en la mayor�a de
los lenguajes (por
ejemplo, Pascal o C); los par�ntesis pueden ser usados para agrupar. Por ejemplo:
>>> 2+2
4
>>> (50-5*6)/4
15
>>> # La divisi�n entera retorna redondeado al piso:
... 7/3
>>> 7/-3
-3
El signo igual (=) es usado para asignar un valor a una variable. Luego, ning�n
resultado es mostrado
antes del pr�ximo prompt:
>>> ancho = 20
>>> largo = 5*9
>>> ancho * largo
>>> y
>>> z
Las variables deben estar "definidas" (con un valor asignado) antes de que puedan
usarse, o un error
ocurrir�:
7.5
>>> 7.0 / 2
3.5
Los n�meros complejos tambi�n est�n soportados; los n�meros imaginarios son
escritos con el sufijo de
j o J. Los n�meros complejos con un componente real que no sea cero son escritos
como
(real+imagj), o pueden ser escrito con la funci�n complex(real, imag).
>>> 1j* 1J
(-1+0j)
16
>>> 1j * complex(0,1)
(-1+0j)
>>> 3+1j*3
(3+3j)
>>> (3+1j)*3
(9+3j)
>>> (1+2j)/(1+1j)
(1.5+0.5j)
Los n�meros complejos son siempre representados como dos n�meros de punto flotante,
la parte real y la
imaginaria. Para extraer estas partes desde un n�mero complejo z, us� z.real y
z.imag.
>>> a=1.5+0.5j
>>> a.real
1.5
>>> a.imag
0.5
>>> a=3.0+4.0j
>>> float(a)
...
>>> a.real
3.0
>>> a.imag
4.0
5.0
>>>
En el modo interactivo, la �ltima expresi�n impresa es asignada a la variable _.
Esto significa que cuando
est�s usando Python como una calculadora de escritorio, es m�s f�cil seguir
calculando, por ejemplo:
12.5625
>>> precio + _
113.0625
>>> round(_, 2)
113.06
>>>
17
Esta variable deber�a ser tratada como de s�lo lectura por el usuario. No le
asignes expl�citamente un
valor; crear�s una variable local independiente con el mismo nombre enmascarando la
variable con el
comportamiento m�gico.
Cadenas de caracteres
Adem�s de n�meros, Python puede manipular cadenas de texto, las cuales pueden ser
expresadas de
distintas formas. Pueden estar encerradas en comillas simples o dobles:
'huevos y pan'
>>> 'doesn\'t'
"doesn't"
>>> "doesn't"
"doesn't"
'"Si," le dijo.'
'"Si," le dijo.'
print hola
Not� que de todas formas se necesita embeber los salto de l�neas con \n; la nueva
l�nea que sigue a la
barra invertida final es descartada. Este ejemplo imprimir�a:
O, las cadenas de texto pueden ser rodeadas en un par de comillas triples: """ o
'''. No se necesita
escapar los finales de l�nea cuando se utilizan comillas triples, pero ser�n
incluidos en la cadena.
print """
Uso: algo [OPTIONS]
18
-h Muestra el mensaje de uso
-H nombrehost Nombre del host al cual conectarse
"""
print hola
...imprimir�:
Las cadenas de texto pueden ser concatenadas (pegadas juntas) con el operador + y
repetidas con *:
'AyudaA'
Dos cadenas de texto juntas son autom�ticamente concatenadas; la primer l�nea del
ejemplo anterior
podr�a haber sido escrita palabra = 'Ayuda' 'A'; esto solo funciona con dos
literales, no con
expresiones arbitrarias:
'cadena'
19
SyntaxError: invalid syntax
>>> palabra[4]
'a'
>>> palabra[0:2]
'Ay'
>>> palabra[2:4]
'ud'
Los �ndices de las rebanadas tienen valores por defecto �tiles; el valor por
defecto para el primer �ndice es
cero, el valor por defecto para el segundo �ndice es la longitud de la cadena a
rebanar.
'Ay'
'udaA'
Sin embargo, crear una nueva cadena con contenido combinado es f�cil y eficiente:
'xyudaA'
'MasA'
'AyudaA'
'AyudaA'
20
Los �ndices degenerados en las rebanadas son manejados bien: un �ndice muy largo es
reemplazado por
la longitud de la cadena, un l�mite superior m�s chico que el l�mite menor retorna
una cadena vac�a.
>>> palabra[1:100]
'yudaA'
>>> palabra[10:]
''
>>> palabra[2:1]
''
Los �ndices pueden ser n�meros negativos, para empezar a contar desde la derecha.
Por ejemplo:
'A'
'a'
'aA'
'Ayud'
Pero not� que -0 es en realidad lo mismo que 0, �por lo que no cuenta desde la
derecha!
'A'
Los �ndices negativos fuera de rango son truncados, pero esto no funciona para
�ndices de un solo
elemento (no rebanada):
>>> palabra[-100:]
'AyudaA'
Una forma de recordar c�mo funcionan las rebanadas es pensar en los �ndices como
puntos entre
caracteres, con el punto a la izquierda del primer car�cter numerado en 0. Luego,
el punto a la derecha del
�ltimo car�cter de una cadena de n caracteres tienen �ndice n, por ejemplo:
+---+---+---+---+---+---+
| A | y | u | d | a | A |
+---+---+---+---+---+---+
0 1 2 3 4 5 6
-6 -5 -4 -3 -2 -1
21
etiquetados i y j, respectivamente.
>>> s = 'supercalifrastilisticoespialidoso'
>>> len(s)
Ver tambi�n
typesseq
Las cadenas de texto y la cadenas de texto Unicode descritas en la siguiente
secci�n son ejemplos de
tipos secuencias, y soportan las operaciones comunes para esos tipos.
string-methods
Tanto las cadenas de texto normales como las cadenas de texto Unicode soportan una
gran cantidad
de m�todos para transformaciones b�sicas y b�squeda.
new-string-formatting
string-formatting
Aqu� se describe con m�s detalle las operaciones viejas para formateo usadas cuando
una cadena de
texto o una cadena Unicode est�n a la izquierda del operador %.
Desde la versi�n 2.0 de Python, se encuentra disponible un nuevo tipo de datos para
que los
programadores almacenen texto: el objeto Unicode. Puede ser usado para almacenar y
manipular datos
Unicode (ver http://www.unicode.org/) y se integran bien con los objetos existentes
para cadenas de texto,
mediante auto-conversi�n cuando es necesario.
Unicode tiene la ventaja de tener un n�mero ordinal para cada car�cter usado tanto
en textos modernos
como antiguos. Previamente, hab�a s�lo 256 ordinales posibles para los caracteres
en scripts. Los textos
eran t�picamente asociados a un c�digo que relaciona los ordinales a caracteres en
scripts. Esto lleva a
mucha confusi�n, especialmente al internacionalizar software. Unicode resuelve
estos problemas
definiendo una sola codificaci�n para todos los scripts.
Crear cadenas Unicode en Python es tan simple como crear cadenas de texto normales:
>>> u'Hola Mundo!'
u'Hola Mundo!'
La 'u' al frente de la comilla indica que se espera una cadena Unicode. Si quer�s
incluir caracteres
especiales en la cadena, pod�s hacerlo usando una forma de escapar caracteres
Unicode provista por
22
Python. El siguiente ejemplo muestra c�mo:
>>> u'Hola\u0020Mundo!'
u'Hola Mundo!'
La secuencia de escape \u0020 indica que se debe insertar el car�cter Unicode con
valor ordinal 0x0020
(el espacio en blanco) en la posici�n dada.
Tambi�n existe un modo crudo para expertos, del mismo modo que con las cadenas de
texto normales.
Deb�s anteponer 'ur' a la comilla inicial para que Python use el modo de escape
crudo de Unicode. Solo
se aplicar� la conversi�n \uXXXX si hay un n�mero impar de barras invertidas frente
a la 'u'.
>>> ur'Hola\u0020Mundo!'
u'Hola Mundo!'
>>> ur'Hola\\u0020Mundo!'
u'Hola\\\\u0020Mundo!'
El modo crudo es �til principalmente cuando ten�s que insertar muchas barras
invertidas, como puede
suceder al trabajar con expresiones regulares.
Adem�s de estas codificaciones est�ndar, Python provee muchas m�s formas de crear
cadenas de texto
Unicode en las bases de codificaciones conocidas.
>>> u"abc"
u'abc'
>>> str(u"abc")
'abc'
>>> u"���"
u'\xe4\xf6\xfc'
>>> str(u"���")
...
Para convertir una cadena Unicode en una cadena de 8-bit utilizando un c�digo en
particular, los objetos
Unicode tienen un m�todo encode() que toma un argumento, el nombre del c�digo. Se
prefieren los
nombres en min�sculas para los nombres de los c�digos.
>>> u"���".encode('utf-8')
'\xc3\xa4\xc3\xb6\xc3\xbc'
23
Si ten�s datos en un c�digo en particular y quer�s producir la cadena Unicode
correspondiente, pod�s
usar la funci�n unicode() con el nombre del c�digo como segundo argumento.
u'\xe4\xf6\xfc'
Listas
Python tiene varios tipos de datos compuestos, usados para agrupar otros valores.
El m�s vers�til es la
lista, la cual puede ser escrita como una lista de valores separados por coma
(�tems) entre corchetes. No
es necesario que los �tems de una lista tengan todos el mismo tipo.
Como los �ndices de las cadenas de texto, los �ndices de las listas comienzan en 0,
y las listas pueden ser
rebanadas, concatenadas y todo lo dem�s:
>>> a[0]
'pan'
>>> a[3]
1234
>>> a[-2]
100
>>> a[1:-1]
['huevos', 100]
['pan', 'huevos', 100, 'pan', 'huevos', 100, 'pan', 'huevos', 100, 'Boo!']
>>> a
Tambi�n es posible asignar a una rebanada, y esto incluso puede cambiar la longitud
de la lista o vaciarla
totalmente:
24
>>> a
[123, 1234]
>>> # Vaciar la lista: reemplazar todos los items con una lista vac�a
>>> a[:] = []
>>> a
[]
Es posible anidar listas (crear listas que contengan otras listas), por ejemplo:
>>> q=[2, 3]
>>> p=[1, q, 4]
>>> len(p)
>>> p[1]
[2, 3]
>>> p[1][0]
>>> q
[2, 3, 'extra']
25
Primeros pasos hacia la programaci�n
Por supuesto, podemos usar Python para tareas m�s complicadas que sumar dos y dos.
Por ejemplo,
podemos escribir una subsecuencia inicial de la serie de Fibonacci as�:
... print b
... a, b = b, a+b
...
1
1
2
3
5
8
�
La primer l�nea contiene una asignaci�n m�ltiple: las variables``a`` y b toman en
forma simultanea
los nuevos valores 0 y 1. En la �ltima linea esto es vuelto a usar, demostrando que
las expresiones
a la derecha son evaluadas antes de que suceda cualquier asignaci�n. Las
expresiones a la
derecha son evaluadas de izquierda a derecha.
�
El bucle while se ejecuta mientras la condici�n (aqu�: b < 10) sea verdadera. En
Python, como
en C, cualquier entero distinto de cero es verdadero; cero es falso. La condici�n
tambi�n puede ser
una cadena de texto o una lista, de hecho cualquier secuencia; cualquier cosa con
longitud distinta
de cero es verdadero, las secuencias vac�as son falsas. La prueba usada en el
ejemplo es una
comparaci�n simple. Los operadores est�ndar de comparaci�n se escriben igual que en
C: <
(menor qu�), > (mayor qu�), == (igual a), <= (menor o igual qu�), >= (mayor o igual
qu�) y !=
(distinto a).
�
El cuerpo del bucle est� sangrado: la sangr�a es la forma que usa Python para
agrupar
declaraciones. El int�rprete interactivo de Python (�a�n!) no provee una facilidad
inteligente para
editar l�neas, as� que deb�s teclear un tab o espacio(s) para cada l�nea sangrada.
En la pr�ctica
vas a preparar entradas m�s complicadas para Python con un editor de texto; la
mayor�a de los
editores de texto tienen la facilidad de agregar la sangr�a autom�ticamente. Al
ingresar una
declaraci�n compuesta en forma interactiva, deb�s finalizar con una l�nea en blanco
para indicar
que est� completa (ya que el analizador no puede adivinar cuando tecleaste la
�ltima l�nea). Not�
que cada l�nea de un bloque b�sico debe estar sangrada de la misma forma.
26
�
La declaraci�n print escribe el valor de la o las expresiones que se le pasan.
Difiere de
simplemente escribir la expresi�n que se quiere mostrar (como hicimos antes en los
ejemplos de la
calculadora) en la forma en que maneja m�ltiples expresiones y cadenas. Las cadenas
de texto
son impresas sin comillas, y un espacio en blanco es insertado entre los elementos,
as� pod�s
formatear cosas de una forma agradable:
>>> i= 256*256
El valor de i es 65536
>>> a, b = 0, 1
>>> while b< 1000:
... print b,
... a, b = b, a+b
...
27
M�s herramientas para control de flujo
La sentencia if
Tal vez el tipo m�s conocido de sentencia sea el if. Por ejemplo:
>>> if x< 0:
... x= 0
... elif x == 0:
... elif x == 1:
... else:
...
'Mas'
Puede haber cero o m�s bloques elif, y el bloque else es opcional. La palabra
reservada 'elif' es
una abreviaci�n de 'else if', y es �til para evitar un sangrado excesivo. Una
secuencia if ... elif ...
elif ... sustituye las sentencias switch o case encontradas en otros lenguajes.
La sentencia for
La sentencia for en Python difiere un poco de lo que uno puede estar acostumbrado
en lenguajes como
C o Pascal. En lugar de siempre iterar sobre una progresi�n aritm�tica de n�meros
(como en Pascal) o
darle al usuario la posibilidad de definir tanto el paso de la iteraci�n como la
condici�n de fin (como en C),
la sentencia for de Python itera sobre los �tems de cualquier secuencia (una lista
o una cadena de
texto), en el orden que aparecen en la secuencia. Por ejemplo:
gato 4
ventana 7
28
defenestrado 12
>>> for x in a[:]: # hacer una copia por rebanada de toda la lista
... if len(x) > 6: a.insert(0, x)
...
>>> a
La funci�n range()
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
El valor final dado nunca es parte de la lista; range(10) genera una lista de 10
valores, los �ndices
correspondientes para los �tems de una secuencia de longitud 10. Es posible hacer
que el rango empiece
con otro n�mero, o especificar un incremento diferente (incluso negativo; algunas
veces se lo llama
'paso'):
[5, 6, 7, 8, 9]
[0, 3, 6, 9]
>>> range(-10,-100,-30)
...
0 Mary
1 tenia
2 un
3 corderito
En la mayor�a de los casos, sin embargo, conviene usar la funci�n enumerate(), mir�
tut-loopidioms.
29
Las sentencias break, continue, y else en
lazos
Las sentencias de lazo pueden tener una cl�usula else que es ejecutada cuando el
lazo termina, luego
de agotar la lista (con for) o cuando la condici�n se hace falsa (con while), pero
no cuando el lazo es
terminado con la sentencia break. Se ejemplifica en el siguiente lazo, que busca
n�meros primos:
2 es un numero primo
3 es un numero primo
4 es igual a 2 * 2
5 es un numero primo
6 es igual a 2 * 3
7 es un numero primo
8 es igual a 2 * 4
9 es igual a 3 * 3
La sentencia pass
La sentencia pass no hace nada. Se puede usar cuando una sentencia es requerida por
la sint�xis pero
el programa no requiere ninguna acci�n. Por ejemplo:
Definiendo funciones
Podemos crear una funci�n que escriba la serie de Fibonacci hasta un l�mite
determinado:
La palabra reservada def se usa para definir funciones. Debe seguirle el nombre de
la funci�n y la lista
de par�metros formales entre par�ntesis. Las sentencias que forman el cuerpo de la
funci�n empiezan en
la l�nea siguiente, y deben estar con sangr�a.
La primer sentencia del cuerpo de la funci�n puede ser opcionalmente una cadena de
texto literal; esta es
la cadena de texto de documentaci�n de la funci�n, o docstring. (Pod�s encontrar
m�s acerca de
docstrings en la secci�n tut-docstrings.)
La ejecuci�n de una funci�n introduce una nueva tabla de s�mbolos usada para las
variables locales de la
funci�n. M�s precisamente, todas las asignaciones de variables en la funci�n
almacenan el valor en la
tabla de s�mbolos local; as� mismo la referencia a variables primero mira la tabla
de s�mbolos local, luego
en la tabla de s�mbolos local de las funciones externas, luego la tabla de s�mbolos
global, y finalmente la
tabla de nombres predefinidos. As�, no se les puede asignar directamente un valor a
las variables globales
dentro de una funci�n (a menos se las nombre en la sentencia global), aunque si
pueden ser
referenciadas.
31
siempre una referencia a un objeto, no el valor del objeto). 2 Cuando una funci�n
llama a otra funci�n, una
nueva tabla de s�mbolos local es creada para esa llamada.
>>> fib
>>> f = fib
>>> f(100)
1 1 2 3 5 8 13 21 34 55 89
Viniendo de otros lenguajes, pod�s objetar que fib no es una funci�n, sino un
procedimiento, porque no
devuelve un valor. De hecho, t�cnicamente hablando, los procedimientos s� retornan
un valor, aunque uno
aburrido. Este valor se llama None (es un nombre predefinido). El int�rprete por lo
general no escribe el
valor None si va a ser el �nico valor escrito. Si realmente se quiere, se puede
verlo usando print:
>>> fib(0)
>>> print fib(0)
None
Es simple escribir una funci�n que retorne una lista con los n�meros de la serie de
Fibonacci en lugar de
imprimirlos:
... result = []
... a, b = 0, 1
... a, b = b, a+b
...
>>> f100
# escribir el resultado
�
La sentencia return devuelve un valor en una funci�n. return sin una expresi�n como
Tambi�n es posible definir funciones con un n�mero variable de argumentos. Hay tres
formas que pueden
ser combinadas.
La forma m�s �til es especificar un valor por omisi�n para uno o m�s argumentos.
Esto crea una funci�n
que puede ser llamada con menos argumentos que los que permite. Por ejemplo:
while True:
ok = raw_input(prompt)
if ok in ('s', 'S', 'si', 'Si', 'SI'):
return True
if ok in ('n', 'no', 'No', 'NO'):
return False
reintentos = reintentos -1
if reintentos < 0:
raise IOError('usuario duro')
print queja
�
pasando s�lo el argumento obligatorio: pedir_confirmacion('�Realmente queres
salir?')
�
pasando uno de los argumentos opcionales: pedir_confirmacion('�Sobreescribir
archivo?', 2)
�
o pasando todos los argumentos: pedir_confirmacion('�Sobreescribir archivo?',
2, "Vamos, solo si o no!)
Este ejemplo tambi�n introduce la palabra reservada in, la cual prueba si una
secuencia contiene o no un
determinado valor.
33
i= 5
def f(arg=i):
print arg
i= 6
f()
...imprimir� 5.
Advertencia importante: El valor por omisi�n es evaluado solo una vez. Existe una
diferencia cuando el
valor por omisi�n es un objeto mutable como una lista, diccionario, o instancia de
la mayor�a de las clases.
Por ejemplo, la siguiente funci�n acumula los argumentos que se le pasan en
subsiguientes llamadas:
print f(1)
print f(2)
print f(3)
Imprimir�:
[1]
[1, 2]
[1, 2, 3]
Si no se quiere que el valor por omisi�n sea compartido entre subsiguientes
llamadas, se pueden escribir
la funci�n as�:
L = []
L.append(a)
return L
Las funciones tambi�n puede ser llamadas nombrando a los argumentos de la forma
keyword = value.
Por ejemplo, la siguiente funci�n:
loro(1000)
loro(accion='EXPLOTARRRRR', tension=1000000)
loro('mil', estado='boca arriba')
loro('un millon', 'rostizado', 'saltar')
En general, una lista de argumentos debe tener todos sus argumentos posicionales
seguidos por los
argumentos nombrados, d�nde las palabras claves deben ser elegidas entre los
nombres de los
par�metros formales. No es importante si un par�metro formal tiene un valor por
omisi�n o no. Ning�n
argumento puede recibir un valor m�s de una vez (los nombres de par�metros formales
correspondientes
a argumentos posicionales no pueden ser usados como palabras clave en la misma
llamada). Aqu� hay un
ejemplo que falla debido a esta restricci�n:
35
for c in claves:
print c, ":", palabrasclaves[c]
-- �Tiene Limburger ?
-- Lo siento, nos quedamos sin Limburger
Es muy liquido, sr.
Realmente es muy muy liquido, sr.
La situaci�n inversa ocurre cuando los argumentos ya est�n en una lista o tupla
pero necesitan ser
desempaquetados para llamar a una funci�n que requiere argumentos posicionales
separados. Por
ejemplo, la funci�n predefinida range() espera los argumentos inicio y fin. Si no
est�n disponibles en
forma separada, se puede escribir la llamada a la funci�n con el operador para
desempaquetar
argumentos de una lista o una tupla *::
36
>>> range(3, 6) # llamada normal con argumentos separados
[3, 4, 5]
>>> args = [3, 6]
>>> range(*args) # llamada con argumentos desempaquetados de una lista
[3, 4, 5]
Del mismo modo, los diccionarios pueden entregar argumentos nombrados con el
operador **::
42
>>> f(1)
43
37
Cadenas de texto de documentaci�n
La primer l�nea debe ser siempre un resumen corto y conciso del prop�sito del
objeto. Para ser breve, no
se debe mencionar expl�citamente el nombre o tipo del objeto, ya que estos est�n
disponibles de otros
modos (excepto si el nombre es un verbo que describe el funcionamiento de la
funci�n). Esta l�nea debe
empezar con una letra may�scula y terminar con un punto.
Ahora que est�s a punto de escribir piezas de Python m�s largas y complejas, es un
buen momento para
hablar sobre estilo de codificaci�n. La mayor�a de los lenguajes pueden ser
escritos (o mejor dicho,
formateados) con diferentes estilos; algunos son mas f�ciles de leer que otros.
Hacer que tu c�digo sea
m�s f�cil de leer por otros es siempre una buena idea, y adoptar un buen estilo de
codificaci�n ayuda
tremendamente a lograrlo.
38
Para Python, PEP 8 se erigi� como la gu�a de estilo a la que m�s proyectos
adhirieron; promueve un estilo
de codificaci�n f�cil de leer y visualmente agradable. Todos los desarrolladores
Python deben leerlo en
alg�n momento; aqu� est�n extra�dos los puntos m�s importantes:
�
Usar sangr�as de 4 espacios, no tabs.
4 espacios son un buen compromiso entre una sangr�a peque�a (permite mayor nivel de
sangrado)y una sangr�a grande (m�s f�cil de leer). Los tabs introducen confusi�n y
es mejor
dejarlos de lado.
�
Recortar las l�neas para que no superen los 79 caracteres.
Esto ayuda a los usuarios con pantallas peque�as y hace posible tener varios
archivos de c�digo
abiertos, uno al lado del otro, en pantallas grandes.
�
Usar l�neas en blanco para separar funciones y clases, y bloques grandes de c�digo
dentro de
funciones.
�
Cuando sea posible, poner comentarios en una sola l�nea.
�
Usar docstrings.
�
Usar espacios alrededor de operadores y luego de las comas, pero no directamente
dentro de
par�ntesis: a = f(1, 2) + g(3, 4).
�
Nombrar las clases y funciones consistentemente; la convenci�n es usar
NotacionCamello para
clases y minusculas_con_guiones_bajos para funciones y m�todos. Siempre us� self
como el nombre para el primer argumento en los m�todos (mir� tut-firstclasses para
m�s
informaci�n sobre clases y m�todos).
�
No usar codificaciones estrafalarias si se espera usar el c�digo en entornos
internacionales. ASCII
plano funciona bien en la mayor�a de los casos.
En realidad, llamadas por referencia de objeto ser�a una mejor descripci�n, ya que
si se pasa
un objeto mutable, quien realiza la llamada ver� cualquier cambio que se realice
sobre el
mismo (por ejemplo �tems insertados en una lista).
39
Estructuras de datos
Este cap�tulo describe algunas cosas que ya aprendiste en m�s detalle, y agrega
algunas cosas nuevas
tambi�n.
El tipo de dato lista tiene algunos m�todos m�s. Aqu� est�n todos los m�todos de
los objetos lista:
list.append(x)
Agrega un �tem al final de la lista; equivale a a[len(a):] = [x].
list.extend(L)
Extiende la lista agreg�ndole todos los �tems de la lista dada; equivale a
a[len(a):] = L.
list.insert(i,x)
Inserta un �tem en una posici�n dada. El primer argumento es el �ndice del �tem
delante del cual se
insertar�, por lo tanto a.insert(0, x) inserta al principio de la lista, y
a.insert(len(a), x)
equivale a a.append(x).
list.remove(x)
Quita el primer �tem de la lista cuyo calor sea x. Es un error si no existe tal
�tem.
list.pop([i])
Quita el �tem en la posici�n dada de la lista, y lo devuelve. Si no se especifica
un �ndice, a.pop()
quita y devuelve el �ltimo �tem de la lista. (Los corchetes que encierran a i en la
firma del m�todo
denotan que el par�metro es opcional, no que deber�as escribir corchetes en esa
posici�n. Ver�s esta
notaci�n con frecuencia en la Referencia de la Biblioteca de Python.)
list.index(x)
Devuelve el �ndice en la lista del primer �tem cuyo valor sea x. Es un error si no
existe tal �tem.
list.count(x)
Devuelve el n�mero de veces que x aparece en la lista.
list.sort()
Ordena los �tems de la lista, in situ.
list.reverse()
Invierte los elementos de la lista, in situ.
2 1 0
>>> a.insert(2,-1)
40
>>> a.append(333)
>>> a
>>> a.index(333)
>>> a.remove(333)
>>> a
>>> a.reverse()
>>> a
>>> a.sort()
>>> a
Los m�todos de lista hacen que resulte muy f�cil usar una lista como una pila,
donde el �ltimo elemento
a�adido es el primer elemento retirado ("�ltimo en entrar, primero en salir"). Para
agregar un �tem a la
cima de la pila, use append(). Para retirar un �tem de la cima de la pila, use
pop() sin un �ndice
expl�cito. Por ejemplo:
[3, 4, 5, 6, 7]
>>> stack.pop()
>>> stack
[3, 4, 5, 6]
>>> stack.pop()
>>> stack.pop()
>>> stack
[3, 4]
41
Usando listas como colas
Tambi�n puedes usar una lista convenientemente como una cola, donde el primer
elemento a�adido es el
primer elemento retirado ("primero en entrar, primero en salir"). Para agregar un
�tem al final de la cola,
use append(). Para retirar un �tem del frente de la pila, use pop() con 0 como
�ndice. Por ejemplo:
Hay tres funciones integradas que son muy �tiles cuando se usan con listas:
filter(), map(), y
reduce().
Se puede pasar m�s de una secuencia; la funci�n debe entonces tener tantos
argumentos como
secuencias haya y es llamada con el �tem correspondiente de cada secuencia (o None
si alguna
secuencia es m�s corta que otra). Por ejemplo:
42
>>> map(add, sec, sec)
Un tercer argumento puede pasarse para indicar el valor inicial. En este caso el
valor inicial se devuelve
para una secuencia vac�a, y la funci�n se aplica primero al valor inicial y el
primer �tem de la secuencia,
entonces al resultado y al siguiente �tem, y as� sucesivamente. Por ejemplo,
55
>>> sum([])
Las listas por comprensi�n proveen una forma concisa de crear listas sin tener que
recurrir al uso de
map(), filter() y/o lambda. La definici�n resultante de la lista a menudo tiende a
ser m�s clara que
las listas formadas usando esas construcciones.
Cada lista por comprensi�n consiste de una expresi�n seguida por una cl�usula for,
luego cero o m�s
cl�usulas for o if. El resultado ser� una lista que resulta de evaluar la expresi�n
en el contexto de las
cl�usulas for y if que sigan. Si la expresi�n evalua a una tupla, debe encerrarse
entre par�ntesis.
>>> frutafresca = [' banana', ' mora de Logan ', 'maracuya ']
>>> [arma.strip() for arma in frutafresca]
43
[6, 12, 18]
[12, 18]
[]
>>> [x, x**2 for x in vec] # error - se requieren par�ntesis para tuplas
...
Las listas por comprensi�n son mucho m�s flexibles que map() y pueden aplicarse a
expresiones
complejas y funciones anidadas:
Si tienes el est�mago suficiente, las listas por comprensi�n pueden anidarse. Son
una herramienta
poderosa pero, como toda herramienta poderosa, deben usarse con cuidado, o ni
siquiera usarse.
Considera el siguiente ejemplo de una matriz de 3x3 como una lista que contiene
tres listas, una por fila:
>>> mat = [
Ahora, si quisieras intercambiar filas y columnas, podr�as usar una lista por
comprensi�n:
44
>>> print [[fila[i] for fila in mat] for i in [0, 1, 2]]
Para evitar aprensi�n cuando se anidan lista por comprensi�n, lee de derecha a
izquierda.
Una versi�n m�s detallada de este retazo de c�digo muestra el flujo de manera
expl�cita:
>>> zip(*mat)
La instrucci�n del
Hay una manera de quitar un �tem de una lista dado su �ndice en lugar de su valor:
la instrucci�n del.
Esta es diferente del m�todo pop(), el cual devuelve un valor. La instrucci�n del
tambi�n puede usarse
para quitar secciones de una lista o vaciar la lista completa (lo que hac�amos
antes asignando una lista
vac�a a la secci�n). Por ejemplo:
[]
>>> del a
Hacer referencia al nombre a de aqu� en m�s es un error (al menos hasta que se le
asigne otro valor).
Veremos otros usos para del m�s adelante.
45
Tuplas y secuencias
Vimos que las listas y cadenas tienen propiedades en com�n, como el indizado y las
operaciones de
seccionado. Estas son dos ejemplos de datos de tipo secuencia (ver typesseq). Como
Python es un
lenguaje en evoluci�n, otros datos de tipo secuencia pueden agregarse. Existe otro
dato de tipo secuencia
est�ndar: la tupla.
Una tupla consiste de un n�mero de valores separados por comas, por ejemplo:
12345
>>> t
Como puedes ver, en la salida las tuplas siempre se encierran entre par�ntesis,
para que las tuplas
anidadas puedan interpretarse correctamente; pueden ingresarse con o sin
par�ntesis, aunque a menudo
los par�ntesis son necesarios de todas formas (si la tupla es parte de una
expresi�n m�s grande).
Las tuplas tienen muchos usos. Por ejemplo: pares ordenados (x, y), registros de
empleados de una base
de datos, etc. Las tuplas, al igual que las cadenas, son inmutables: no es posible
asignar a los �tems
individuales de una tupla (aunque puedes simular bastante ese efecto mediante
seccionado y
concatenaci�n). Tambi�n es posible crear tuplas que contengan objetos mutables como
listas.
>>> len(singleton)
>>> singleton
('hola',)
46
>>> x, y, z = t
Conjuntos
Python tambi�n incluye un tipo de dato para conjuntos. Un conjunto es una colecci�n
no ordenada y sin
elementos repetidos. Los usos b�sicos de �stos incluyen verificaci�n de pertenencia
y eliminaci�n de
entradas duplicadas. Los conjuntos tambi�n soportan operaciones matem�ticas como la
uni�n,
intersecci�n, diferencia, y diferencia sim�trica.
True
False
>>> # veamos las operaciones para las letras �nicas de dos palabras
...
>>> a = set('abracadabra')
>>> b = set('alacazam')
>>> a # letras �nicas en a
set(['a', 'r', 'b', 'c', 'd'])
set(['a', 'c'])
47
Diccionarios
Otro tipo de dato �til inclu�do en Python es el diccionario (ver typesmapping). Los
diccionarios se
encuentran a veces en otros lenguajes como "memorias asociativas" o "arreglos
asociativos". A diferencia
de las secuencias, que se indexan mediante un rango num�rico, los diccionarios se
indexan con claves,
que pueden ser cualquier tipo inmutable; las cadenas y n�meros siempre pueden ser
claves. Las tuplas
pueden usarse como claves si solamente contienen cadenas, n�meros o tuplas; si una
tupla contiene
cualquier objeto mutable directa o indirectamente, no puede usarse como clave. No
pod�s usar listas
como claves, ya que las listas pueden modificarse usando asignaci�n por �ndice,
asignaci�n por secci�n, o
m�todos como append() y extend().
Las operaciones principales sobre un diccionario son guardar un valor con una clave
y extraer ese valor
dada la clave. Tambi�n es posible borrar un par clave:valor con del. Si us�s una
clave que ya est� en uso
para guardar un valor, el valor que estaba asociado con esa clave se pierde. Es un
error extraer un valor
usando una clave no existente.
El m�todo keys() de un diccionario devuelve una lista de todas las claves en uso de
ese diccionario, en
un orden arbitrario (si la quer�s ordenada, simplemente us� el metodo sort() sobre
la lista de claves).
Para verificar si una clave est� en el diccionario, utiliz� la palabra clave in.
>>> tel['jack']
>>> tel.keys()
True
48
>>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
Cuando las claves son cadenas simples, a veces resulta m�s f�cil especificar los
pares usando
argumentos por palabra clave:
T�cnicas de iteraci�n
gallahad el puro
robin el valiente
Cuando se itera sobre una secuencia, se puede obtener el �ndice de posici�n junto a
su valor
correspondiente usando la funci�n enumerate().
0 ta
1 te
2 ti
Para iterar sobre dos o m�s secuencias al mismo tiempo, los valores pueden
emparejarse con la funci�n
zip().
>>> preguntas = ['nombre', 'objetivo', 'color favorito']
>>> respuestas = ['lancelot', 'el santo grial', 'azul']
>>> for p, r in zip(preguntas, respuestas):
... print 'Cual es tu {0}? {1}.'.format(p, r)
...
49
Cual es tu objetivo? el santo grial.
Cual es tu color favorito? azul.
9
7
5
3
1
Para iterar sobre una secuencia ordenada, se utiliza la funci�n sorted() la cual
devuelve una nueva
lista ordenada dejando a la original intacta.
banana
manzana
naranja
pera
Las comparaciones pueden combinarse mediante los operadores booleanos and y or, y
el resultado de
una comparaci�n (o de cualquier otra expresi�n booleana) puede negarse con not.
Estos tienen
prioridades menores que los operadores de comparaci�n; entre ellos not tiene la
mayor prioridad y or la
menor, o sea que A and not B or C equivale a (A and (not B)) or C. Como siempre,
los
par�ntesis pueden usarse para expresar la composici�n deseada.
50
Los operadores booleanos and y or son los llamados operadores cortocircuito: sus
argumentos se
eval�an de izquierda a derecha, y la evaluaci�n se detiene en el momento en que se
determina su
resultado. Por ejemplo, si A y C son verdaderas pero B es falsa, en A and B and C
no se eval�a la
expresi�n C. Cuando se usa como un valor general y no como un booleano, el valor
devuelto de un
operador cortocircuito es el �ltimo argumento evaluado.
'Trondheim'
Las secuencias pueden compararse con otros objetos del mismo tipo de secuencia. La
comparaci�n usa
orden lexicogr�fico: primero se comparan los dos primeros �tems, si son diferentes
esto ya determina el
resultado de la comparaci�n; si son iguales, se comparan los siguientes dos �tems,
y as� sucesivamente
hasta llegar al final de alguna de las secuencias. Si dos �tems a comparar son
ambos secuencias del
mismo tipo, la comparaci�n lexicogr�fica es recursiva. Si todos los �tems de dos
secuencias resultan
iguales, se considera que las secuencias son iguales. Si una secuencia es una
subsecuencia inicial de la
otra, la secuencia m�s corta es la menor. El orden lexicogr�fico para cadenas de
caracteres utiliza el
orden ASCII para caracteres individuales. Algunos ejemplos de comparaciones entre
secuencias del
mismo tipo:
(1, 2, 3) <(1, 2, 4)
[1, 2, 3] <[1, 2, 4]
'ABC' < 'C' < 'Pascal' < 'Python'
(1, 2, 3, 4) <(1, 2, 4)
(1, 2) <(1, 2,-1)
(1, 2, 3) ==(1.0, 2.0, 3.0)
(1, 2, ('aa', 'ab')) < (1, 2, ('abc', 'a'), 4)
Observ� que comparar objetos de diferentes tipos es legal. El resultado es
determin�stico pero arbitrario:
los tipos se ordenan por su nombre. Por lo tanto, una lista (list) siempre eval�a
como menor que una
cadena (string).
51
M�dulos
Si sal�s del int�rprete de Python y entr�s de nuevo, las definiciones que hiciste
(funciones y variables) se
pierden. Por lo tanto, si quer�s escribir un programa m�s o menos largo, es mejor
que uses un editor de
texto para preparar la entrada para el interprete y ejecutarlo con ese archivo como
entrada. Esto es
conocido como crear un gui�n, o script. Si tu programa se vuelve m�s largo, quiz�s
quieras separarlo en
distintos archivos para un mantenimiento m�s f�cil. Quiz�s tambi�n quieras usar una
funci�n �til que
escribiste desde distintos programas sin copiar su definici�n a cada programa.
Para soportar esto, Python tiene una manera de poner definiciones en un archivo y
usarlos en un script o
en una instancia interactiva del int�rprete. Tal archivo es llamado m�dulo; las
definiciones de un m�dulo
pueden ser importadas a otros m�dulos o al m�dulo principal (la colecci�n de
variables a las que ten�s
acceso en un script ejecutado en el nivel superior y en el modo calculadora).
print b,
a, b = b, a+b
resultado.append(b)
a, b = b, a+b
return resultado
Ahora entr� al int�rprete de Python e import� este m�dulo con la siguiente orden:
>>> fibo.fib(1000)
>>> fibo.fib2(100)
52
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
>>> fibo.__name__
'fibo'
Cada m�dulo tiene su propio espacio de nombres, el que es usado como espacio de
nombres global por
todas las funciones definidas en el m�dulo. Por lo tanto, el autor de un m�dulo
puede usar variables
globales en el m�dulo sin preocuparse acerca de conflictos con una variable global
del usuario. Por otro
lado, si sab�s lo que est�s haciendo pod�s tocar las variables globales de un
m�dulo con la misma
notaci�n usada para referirte a sus funciones, nombremodulo.nombreitem.
Hay una variante de la declaraci�n import que importa los nombres de un m�dulo
directamente al
espacio de nombres del m�dulo que hace la importaci�n. Por ejemplo:
Esto no introduce en el espacio de nombres local el nombre del m�dulo desde el cual
se est� importando
(entonces, en el ejemplo, fibo no se define).
Hay incluso una variante para importar todos los nombres que un m�dulo define:
Esto importa todos los nombres excepto aquellos que comienzan con un subrayado (_).
53
Nota
Por razones de eficiencia, cada m�dulo se importa una vez por sesi�n del
int�rprete. Por lo tanto, si
modific�s los m�dulos, ten�s que reiniciar el int�rprete -- o, si es s�lo un m�dulo
que quer�s probar
interactivamente, us� reload(), por ejemplo reload(nombremodulo).
...el c�digo en el m�dulo ser� ejecutado, tal como si lo hubieses importado, pero
con __name__ con el
valor de "__main__". Eso significa que agregando este c�digo al final de tu m�dulo:
if __name__ == "__main__":
import sys
fib(int(sys.argv[1]))
...pod�s hacer que el archivo sea utilizable tanto como script, como m�dulo
importable, porque el c�digo
que analiza la linea de �rdenes s�lo se ejecuta si el m�dulo es ejecutado como
archivo principal:
$ python fibo.py 50
1 1 2 3 5 8 13 21 34
>>>
54
directorio default dependiente de la instalaci�n. Esto permite que los programas en
Python que saben lo
que est�n haciendo modifiquen o reemplacen el camino de b�squeda de los m�dulos.
Notar que como el
directorio que contiene el script que se ejecuta est� en el camino de b�squeda, es
importante que el script
no tenga el mismo nombre que un m�dulo est�ndar, o Python intentar� cargar el
script como un m�dulo
cuando ese m�dulo se importe. Esto generalmente ser� un error. Mir� la secci�n tut-
standardmodules
para m�s informaci�n.
Como una importante aceleraci�n del tiempo de arranque para programas cortos que
usan un mont�n de
los m�dulos est�ndar, si un archivo llamado spam.pyc existe en el directorio donde
se encuentra
spam.py, se asume que contiene una versi�n ya "compilada a byte" del m�dulo spam
(lo que se
denomina bytecode). La fecha y hora de modificaci�n del archivo spam.py usado para
crear spam.pyc
se graba en este �ltimo, y el .pyc se ignora si estos no coinciden.
Normalmente, no necesit�s hacer nada para crear el archivo spam.pyc. Siempre que se
compile
satisfactoriamente el spam.py, se hace un intento de escribir la versi�n compilada
al spam.pyc. No es un
error si este intento falla, si por cualquier raz�n el archivo no se escribe
completamente el archivo
spam.pyc resultante se reconocer� como inv�lido luego. El contenido del archivo
spam.pyc es
independiente de la plataforma, por lo que un directorio de m�dulos puede ser
compartido por m�quinas
de diferentes arquitecturas.
�
Cuando se invoca el int�rprete de Python con la opci�n -O, se genera c�digo
optimizado que se
almacena en archivos .pyo. El optimizador actualmente no ayuda mucho; s�lo remueve
las
declaraciones assert. Cuando se usa -O, se optimiza todo el bytecode; se ignoran
los archivos
.pyc y los archivos .py se compilan a bytecode optimizado.
�
Pasando dos opciones -O al int�rprete de Python (-OO) causar� que el compilador
realice
optimizaciones que en algunos raros casos podr�a resultar en programas que
funcionen
incorrectamente. Actualmente, solamente se remueven del bytecode a las cadenas
__doc__,
resultando en archivos .pyo m�s compactos. Ya que algunos programas necesitan tener
disponibles estas cadenas, s�lo deber�as usar esta opci�n si sab�s lo que est�s
haciendo.
�
Un programa no corre m�s r�pido cuando se lee de un archivo .pyc o .pyo que cuando
se lee
del .py; lo �nico que es m�s r�pido en los archivos .pyc o .pyo es la velocidad con
que se
cargan.
�
Cuando se ejecuta un script desde la linea de �rdenes, nunca se escribe el bytecode
del script a
los archivos .pyc o .pyo. Por lo tanto, el tiempo de comienzo de un script puede
reducirse
moviendo la mayor parte de su c�digo a un m�dulo y usando un peque�o script de
arranque que
importe el m�dulo. Tambi�n es posible nombrar a los archivos .pyc o .pyo
directamente desde
la linea de �rdenes.
�
Es posible tener archivos llamados spam.pyc (o spam.pyo cuando se usa la opci�n -O)
sin un
archivo spam.py para el mismo m�dulo. Esto puede usarse para distribuir el c�digo
de una
biblioteca de Python en una forma que es moderadamente dif�cil de hacerle
ingenier�a inversa.
55
� El m�dulo compileall puede crear archivos .pyc (o archivos .pyo cuando se usa la
opci�n
-O) para todos los m�dulos en un directorio.
M�dulos est�ndar
'>>> '
>>> sys.ps2
'... '
La funci�n integrada dir() se usa para encontrar qu� nombres define un m�dulo.
Devuelve una lista
ordenada de cadenas:
56
>>> dir(sys)
Sin argumentos, dir() lista los nombres que ten�s actualmente definidos:
>>> a=[1, 2, 3, 4, 5]
>>> import fibo
>>> fib = fibo.fib
>>> dir()
Not� que lista todos los tipos de nombres: variables, m�dulos, funciones, etc.
dir() no lista los nombres de las funciones y variables integradas. Si quer�s una
lista de esos, est�n
definidos en el m�dulo est�ndar __builtin__:
>>> dir(__builtin__)
Paquetes
Los paquetes son una manera de estructurar los espacios de nombres de Python usando
"nombres de
m�dulos con puntos". Por ejemplo, el nombre de m�dulo A.B designa un subm�dulo
llamado B en un
paquete llamado A. Tal como el uso de m�dulos evita que los autores de diferentes
m�dulos tengan que
preocuparse de los respectivos nombres de variables globales, el uso de nombres de
m�dulos con puntos
evita que los autores de paquetes de muchos m�dulos, como NumPy o la Biblioteca de
Im�genes de
Python (Python Imaging Library, o PIL), tengan que preocuparse de los respectivos
nombres de m�dulos.
Suponete que quer�s designar una colecci�n de m�dulos (un "paquete") para el manejo
uniforme de
archivos y datos de sonidos. Hay diferentes formatos de archivos de sonido
(normalmente reconocidos por
su extensi�n, por ejemplo: .wav, .aiff, .au), por lo que ten�s que crear y mantener
una colecci�n
siempre creciente de m�dulos para la conversi�n entre los distintos formatos de
archivos. Hay muchas
operaciones diferentes que quiz�s quieras ejecutar en los datos de sonido (como
mezclarlos, a�adir eco,
aplicar una funci�n ecualizadora, crear un efecto est�reo artificial), por lo que
ademas estar�s escribiendo
una lista sin fin de m�dulos para realizar estas operaciones. Aqu� hay una posible
estructura para tu
paquete (expresados en t�rminos de un sistema jer�rquico de archivos):
Los archivos __init__.py se necesitan para hacer que Python trate los directorios
como que contienen
paquetes; esto se hace para prevenir directorios con un nombre com�n, como string,
de esconder sin
intenci�n a m�dulos v�lidos que se suceden luego en el camino de b�squeda de
m�dulos. En el caso m�s
simple, __init__.py puede ser solamente un archivo vac�o, pero tambi�n puede
ejecutar c�digo de
inicializaci�n para el paquete o configurar la variable __all__, descrita luego.
Los usuarios del paquete pueden importar m�dulos individuales del mismo, por
ejemplo:
import sound.effects.echo
Esto tambi�n carga el subm�dulo echo, lo deja disponible sin su prefijo de paquete,
por lo que puede
usarse as�:
Not� que al usar from package import item el �tem puede ser tanto un subm�dulo (o
subpaquete)
del paquete, o alg�n otro nombre definido en el paquete, como una funci�n, clase, o
variable. La
declaraci�n import primero verifica si el �tem est� definido en el paquete; si no,
asume que es un
m�dulo y trata de cargarlo. Si no lo puede encontrar, se genera una excepci�n
ImportError.
Por otro lado, cuando se usa la sintaxis como import item.subitem.subsubitem, cada
�tem excepto
el �ltimo debe ser un paquete; el mismo puede ser un m�dulo o un paquete pero no
puede ser una clase,
funci�n o variable definida en el �tem previo.
59
Importando * desde un paquete
La �nica soluci�n es que el autor del paquete provea un �ndice expl�cito del
paquete. La declaraci�n
import usa la siguiente convenci�n: si el c�digo del __init__.py de un paquete
define una lista
llamada __all__, se toma como la lista de los nombres de m�dulos que deber�an ser
importados cuando
se hace from package import *. Es tarea del autor del paquete mantener actualizada
esta lista
cuando se libera una nueva versi�n del paquete. Los autores de paquetes podr�an
decidir no soportarlo, si
no ven un uso para importar * en sus paquetes. Por ejemplo, el archivo
sounds/effects/__init__.py podr�a contener el siguiente c�digo:
Esto significar�a que from sound.effects import * importar�a esos tres subm�dulos
del paquete
sound.
import sound.effects.echo
import sound.effects.surround
from sound.effects import *
En este ejemplo, los m�dulos echo y surround se importan en el espacio de nombre
actual porque est�n
definidos en el paquete sound.effects cuando se ejecuta la declaraci�n
from...import. (Esto
tambi�n funciona cuando se define __all__).
60
Record� que no est� mal usar from paquete import submodulo_especifico! De hecho,
esta
notaci�n se recomienda a menos que el m�dulo que est�s importando necesite usar
subm�dulos con el
mismo nombre desde otros paquetes.
Desde Python 2.5, adem�s de los import relativos impl�citos descritos arriba, pod�s
escribir import
relativos expl�citos con la declaraci�n de la forma from module import name. Estos
import relativos
expl�citos usan puntos adelante para indicar los paquetes actual o padres
involucrados en el import
relativo. En el ejemplo surround, podr�as hacer:
Not� que ambos import, relativos expl�citos e impl�citos, se basan en el nombre del
m�dulo actual. Ya
que el nombre del m�dulo principal es siempre "__main__", los m�dulos pensados para
usarse como
m�dulo principal de una aplicaci�n Python siempre deber�an usar import absolutos.
Los paquetes soportan un atributo especial m�s, __path__. Este se inicializa, antes
de que el c�digo en
ese archivo se ejecute, a una lista que contiene el nombre del directorio donde
est� el paquete. Esta
variable puede modificarse, afectando b�squedas futuras de m�dulos y subpaquetes
contenidos en el
paquete.
61
De hecho las definiciones de funci�n son tambi�n 'declaraciones' que se 'ejecutan';
la
ejecuci�n de una funci�n a nivel de m�dulo mete el nombre de la funci�n en el
espacio de
nombres global.
62
Entrada y salida
Hay diferentes m�todos de presentar la salida de un programa; los datos pueden ser
impresos de una
forma legible por humanos, o escritos a un archivo para uso futuro. Este cap�tulo
discutir� algunas de las
posibilidades.
Nos queda una pregunta, por supuesto: �c�mo convert�s valores a cadenas?
Afortunadamente, Python
tiene maneras de convertir cualquier valor a una cadena: pasalos a las funciones
repr() o str().
La funci�n str() devuelve representaciones de los valores que son bastante legibles
por humanos,
mientras que repr() genera representaciones que pueden ser le�das por el el
int�rprete (o forzar�an un
SyntaxError si no hay sint�xis equivalente). Para objetos que no tienen una
representaci�n en particular
para consumo humano, str() devolver� el mismo valor que repr(). Muchos valores,
como n�meros o
estructuras como listas y diccionarios, tienen la misma representaci�n usando
cualquiera de las dos
funciones. Las cadenas y los n�meros de punto flotante, en particular, tienen dos
representaciones
distintas.
Algunos ejemplos:
'Hola mundo.'
>>> repr(s)
"'Hola mundo.'"
>>> str(0.1)
'0.1'
>>> repr(0.1)
'0.10000000000000001'
>>> x= 10 * 3.25
>>> y= 200 * 200
63
>>> s = 'El valor de x es ' + repr(x) + ', y es ' + repr(y) + '...'
>>> print s
'hola mundo\n'
1 1 1
2 4 8
3 9 27
4 16 64
5 25 125
6 36 216
7 49 343
8 64 512
9 81 729
10 100 1000
1 1 1
2 4 8
3 9 27
4 16 64
5 25 125
6 36 216
7 49 343
8 64 512
9 81 729
10 100 1000
64
(Notar que en el primer ejemplo, un espacio entre cada columna fue agregado por la
manera en que
print trabaja: siempre agrega espacios entre sus argumentos)
Este ejemplo muestra el m�todo rjust() de los objetos cadena, el cual ordena una
cadena a la derecha
en un campo del ancho dado llen�ndolo con espacios a la izquierda. Hay m�todos
similares ljust() y
center(). Estos m�todos no escriben nada, s�lo devuelven una nueva cadena. Si la
cadena de entrada
es demasiado larga, no la truncan, sino la devuelven intacta; esto te romper� la
alineaci�n de tus
columnas pero es normalmente mejor que la alternativa, que te estar�a mintiendo
sobre el valor. (Si
realmente quer�s que se recorte, siempre pod�s agregarle una operaci�n de rebanado,
como en
x.ljust(n)[:n].)
Hay otro m�todo, zfill(), el cual rellena una cadena num�rica a la izquierda con
ceros. Entiende signos
positivos y negativos:
>>> '12'.zfill(5)
'00012'
>>> '-3.14'.zfill(7)
'-003.14'
>>> '3.14159265359'.zfill(5)
'3.14159265359'
Las llaves y caracteres dentro de las mismas (llamados campos de formato) son
reemplazadas con los
objetos pasados en el m�todo str.format(). El n�mero en las llaves se refiere a la
posici�n del objeto
pasado en el m�todo.
carne y huevos
>>> print '{1} y {0}'.format('carne', 'huevos')
huevos y carne
65
Un ': y especificador de formato opcionales pueden ir luego del nombre del campo.
Esto aumenta el
control sobre c�mo el valor es formateado. El siguiente ejemplo trunca Pi a tres
lugares luego del punto
decimal.
Pasando un entero luego del ':' causar� que que el campo sea de un m�nimo n�mero de
caracteres de
ancho. Esto es �til para hacer tablas lindas.
Si ten�s una cadena de formateo realmente larga que no quer�s separar, podr�a ser
bueno que puedas
hacer referencia a las variables a ser formateadas por el nombre en vez de la
posici�n. Esto puede
hacerse simplemente pasando el diccionario y usando corchetes '[]' para acceder a
las claves
Esto se podr�a tambi�n hacer pasando la tabla como argumentos nombrados con la
notaci�n '**'.
Para una completa descripci�n del formateo de cadenas con str.format(), mir� en
formatstrings.
66
El valor de PI es aproximadamente 3.142.
En Windows, agregando 'b' al modo abre al archivo en modo binario, por lo que
tambi�n hay modos
como 'rb', 'wb', y 'r+b'. Windows hace una distinci�n entre archivos binarios y de
texto; los
caracteres de fin de linea en los archivos de texto son autom�ticamente alterados
levemente cuando los
datos son le�dos o escritos. Esta modificaci�n en bambalinas para guardar datos
est� bien con archivos de
texto ASCII, pero corromper� datos binarios como en archivos JPEG o EXE. S� muy
cuidadoso en usar el
modo binario al leer y escribir tales archivos. En Unix, no hay problema en
agregarle una 'b' al modo,
por lo que pod�s usarlo independientemente de la plataforma para todos los archivos
binarios.
El resto de los ejemplos en esta secci�n asumir�n que ya se cre� un objeto archivo
llamado f.
Para leer el contenido de una archivo llam� a f.read(cantidad), el cual lee alguna
cantidad de datos y
los devuelve como una cadena. cantidad es un argumento num�rico opcional. Cuando se
omite cantidad o
es negativo, el contenido entero del archivo ser� leido y devuelto; es tu problema
si el archivo es el doble
de grande que la memoria de tu m�quina. De otra manera, a lo sumo una cantidad de
bytes son le�dos y
devueltos. Si se alcanz� el fin del archivo, f.read() devolver� una cadena vac�a
("").
>>> f.read()
>>> f.read()
67
''
f.readline() lee una sola linea del archivo; el caracter de fin de linea (\n) se
deja al final de la cadena,
y s�lo se omite en la �ltima linea del archivo si el mismo no termina en un fin de
linea. Esto hace que el
valor de retorno no sea ambiguo; si f.readline() devuelve una cadena vac�a, es que
se alcanz� el fin
del archivo, mientras que una linea en blanco es representada por '\n', una cadena
conteniendo s�lo un
�nico fin de linea.
>>> f.readline()
>>> f.readline()
>>> f.readline()
''
>>> f.readlines()
Una forma alternativa a leer lineas es iterar sobre el objeto archivo. Esto es
eficiente en memoria, r�pido, y
conduce a un c�digo m�s simple:
Para escribir algo m�s que una cadena, necesita convertirse primero a una cadena:
68
posici�n es calculada agregando el desplazamiento a un punto de referencia; el
punto de referencia se
selecciona del argumento desde_donde. Un valor desde_donde de 0 mide desde el
comienzo del archivo,
1 usa la posici�n actual del archivo, y 2 usa el fin del archivo como punto de
referencia. desde_donde
puede omitirse, el default es 0, usando el comienzo del archivo como punto de
referencia.
'5'
'd'
Cuando hayas terminado con un archivo, llam� a f.close() para cerrarlo y liberar
cualquier recurso del
sistema tomado por el archivo abierto. Luego de llamar f.close(), los intentos de
usar el objeto archivo
fallar�n autom�ticamente.
>>> f.close()
>>> f.read()
Es una buena pr�ctica usar la declaraci�n with cuando manejamos objetos archivo.
Tiene la ventaja que
el archivo es cerrado apropiadamente luego de que el bloque termina, incluso si se
gener� una excepci�n.
Tambi�n es mucho m�s corto que escribir los equivalentes bloques try-finally
True
Los objetos archivo tienen algunos m�todos m�s, como isatty() y truncate() que son
usados
menos frecuentemente; consult� la Referencia de la Biblioteca para una gu�a
completa sobre los objetos
archivo.
El m�dulo pickle
Las cadenas pueden facilmente escribirse y leerse de un archivo. Los n�meros toman
algo m�s de
esfuerzo, ya que el m�todo read() s�lo devuelve cadenas, que tendr�n que ser
pasadas a una funci�n
como int(), que toma una cadena como '123' y devuelve su valor num�rico 123. Sin
embargo,
cuando quer�s grabar tipos de datos m�s complejos como listas, diccionarios, o
instancias de clases, las
cosas se ponen m�s complicadas.
69
En lugar de tener a los usuarios constantemente escribiendo y debugueando c�digo
para grabar tipos de
datos complicados, Python provee un m�dulo est�ndar llamado pickle. Este es un
asombroso m�dulo
que puede tomar casi cualquier objeto Python (�incluso algunas formas de c�digo
Python!), y convertirlo a
una representaci�n de cadena; este proceso se llama picklear. Reconstruir los
objetos desde la
representaci�n en cadena se llama despicklear. Entre que se picklea y se
despicklea, la cadena que
representa al objeto puede almacenarse en un archivo, o enviarse a una m�quina
distante por una
conexi�n de red.
pickle.dump(x, f)
Para despicklear el objeto, si f es un objeto archivo que fue abierto para lectura:
x = pickle.load(f)
(Hay otras variantes de esto, usadas al picklear muchos objetos o cuando no quer�s
escribir los datos
pickleados a un archivo; consult� la documentaci�n completa para pickle en la
Referencia de la
Biblioteca de Python.)
pickle es la manera est�ndar de hacer que los objetos Python puedan almacenarse y
reusarse por otros
programas o por una futura invocaci�n al mismo programa; el t�rmino t�cnico de esto
es un objeto
persistente. Ya que pickle es tan ampliamente usado, muchos autores que escriben
extensiones de
Python toman el cuidado de asegurarse que los nuevos tipos de datos, como matrices,
puedan ser
adecuadamente pickleados y despickleados.
70
Errores y excepciones
Hasta ahora los mensajes de error no hab�an sido m�s que mencionados, pero si
probaste los ejemplos
probablemente hayas visto algunos. Hay (al menos) dos tipos diferentes de errores:
errores de sintaxis y
excepciones.
Errores de sintaxis
El int�rprete repite la l�nea culpable y muestra una peque�a 'flecha' que apunta al
primer lugar donde se
detect� el error. Este es causado por (o al menos detectado en) el s�mbolo que
precede a la flecha: en el
ejemplo, el error se detecta en el print, ya que faltan dos puntos (':') antes del
mismo. Se muestran el
nombre del archivo y el n�mero de l�nea para que sepas d�nde mirar en caso de que
la entrada venga de
un programa.
Excepciones
>>> 10 *(1/0)
>>> '2' + 2
71
TypeError: cannot concatenate 'str' and 'int' objects
La �ltima l�nea de los mensajes de error indica qu� sucedi�. Las excepciones vienen
de distintos tipos, y
el tipo se imprime como parte del mensaje: los tipos en el ejemplo son:
ZeroDivisionError,
NameError y TypeError. La cadena mostrada como tipo de la excepci�n es el nombre de
la excepci�n
predefinida que ocurri�. Esto es verdad para todas las excepciones predefinidas del
int�rprete, pero no
necesita ser verdad para excepciones definidas por el usuario (aunque es una
convenci�n �til). Los
nombres de las excepciones est�ndar son identificadores incorporados al int�rprete
(no son palabras
clave reservadas).
Manejando excepciones
... try:
... x = int(raw_input(u"Por favor ingrese un n�mero: "))
... break
... except ValueError:
... print u"Oops! No era v�lido. Intente nuevamente..."
...
�
Primero, se ejecuta el bloque try (el c�digo entre las declaraci�n try y except).
�
Si no ocurre ninguna excepci�n, el bloque except se saltea y termina la ejecuci�n
de la declaraci�n
try.
�
Si ocurre una excepci�n durante la ejecuci�n del bloque try, el resto del bloque se
saltea. Luego, si
su tipo coincide con la excepci�n nombrada luego de la palabra reservada except, se
ejecuta el
bloque except, y la ejecuci�n contin�a luego de la declaraci�n try.
�
Si ocurre una excepci�n que no coincide con la excepci�n nombrada en el except,
esta se pasa a
declaraciones try de m�s afuera; si no se encuentra nada que la maneje, es una
excepci�n no
manejada, y la ejecuci�n se frena con un mensaje como los mostrados arriba.
Una declaraci�n try puede tener m�s de un except, para especificar manejadores para
distintas
excepciones. A lo sumo un manejador ser� ejecutado. S�lo se manejan excepciones que
ocurren en el
72
correspondiente try, no en otros manejadores del mismo try. Un except puede nombrar
m�ltiples
excepciones usando par�ntesis, por ejemplo:
El �ltimo except puede omitir nombrar qu� excepci�n captura, para servir como
comod�n. Us� esto con
extremo cuidado, ya que de esta manera es f�cil ocultar un error real de
programaci�n. Tambi�n puede
usarse para mostrar un mensaje de error y luego re-generar la excepci�n
(permiti�ndole al que llama,
manejar tambi�n la excepci�n):
import sys
try:
f = open('miarchivo.txt')
s = f.readline()
i = int(s.strip())
except:
print "Error inesperado:", sys.exc_info()[0]
raise
Las declaraciones try ... except tienen un bloque else opcional, el cual, cuando
est� presente, debe
seguir a los except. Es �til para aquel c�digo que debe ejecutarse si el bloque try
no genera una
excepci�n. Por ejemplo:
else:
f.close()
El uso de else es mejor que agregar c�digo adicional en el try porque evita
capturar accidentalmente
una excepci�n que no fue generada por el c�digo que est� protegido por la
declaraci�n try ... except.
Cuando ocurre una excepci�n, puede tener un valor asociado, tambi�n conocido como
el argumento de la
excepci�n. La presencia y el tipo de argumento depende del tipo de excepci�n.
73
acceder o mostrar los argumentos directamente, sin necesidad de hacer referencia
a .args.
>>> try:
<type 'exceptions.Exception'>
('carne', 'huevos')
('carne', 'huevos')
x = carne
y = huevos
Si una excepci�n tiene un argumento, este se imprime como la �ltima parte (el
'detalle') del mensaje para
las excepciones que no est�n manejadas.
El argumento de raise es una clase o instancia de excepci�n a ser generada. Hay una
sintaxis
alternativa que no se usa m�s, que separa los argumentos de clase y constructor; lo
de arriba podr�a
escribirse como raise NameError, 'Hola'; ya que alguna vez era la �nica opci�n,
esta forma es muy
usada en c�digos viejos.
Si necesit�s determinar cuando una excepci�n fue lanzada pero no quer�s manejarla,
una forma
simplificada de la instrucci�n raise te permite relanzarla:
>>> try:
... raise NameError('Hola')
... except NameError:
Los programas pueden nombrar sus propias excepciones creando una nueva clase
excepci�n. Las
excepciones, t�picamente, deber�n derivar de la clase Exception, directa o
indirectamente. Por ejemplo:
>>> try:
... raise MiError(2*2)
... except MyError as e:
... print u'Ocurri� mi excepci�n, valor:', e.valor
...
75
Ocurri� mi excepci�n, valor: 4
Las clases de Excepciones pueden ser definidas de la misma forma que cualquier otra
clase, pero
usualmente se mantienen simples, a menudo solo ofreciendo un n�mero de atributos
con informaci�n
sobre el error que leer�n los manejadores de la excepci�n. Al crear un m�dulo que
puede lanzar varios
errores distintos, una pr�ctica com�n es crear una clase base para excepciones
definidas en ese m�dulo y
extenderla para crear clases excepciones espec�ficas para distintas condiciones de
error:
class Error(Exception):
pass
class EntradaError(Error):
Atributos:
expresion -- expresion de entrada en la que ocurre el error
mensaje -- explicacion del error
"""
Atributos:
previo -- estado al principio de la transicion
siguiente -- nuevo estado intentado
mensaje -- explicacion de porque la transicion no esta permitida
"""
76
self.mensaje = mensaje
La mayor�a de las excepciones son definidas con nombres que terminan en "Error",
similares a los
nombres de las excepciones est�ndar.
Muchos m�dulos est�ndar definen sus propias excepciones para reportar errores que
pueden ocurrir en
funciones propias. Se puede encontrar m�s informaci�n sobre clases en el cap�tulo
tut-classes.
La declaraci�n try tiene otra cl�usula opcional que intenta definir acciones de
limpieza que deben ser
ejecutadas bajo ciertas circunstancias. Por ejemplo:
>>> try:
... raise KeyboardInterrupt
... finally:
... print 'Chau, mundo!'
...
Chau, mundo!
KeyboardInterrupt
... try:
... result = x / y
... except ZeroDivisionError:
... print "�division por cero!"
... else:
... print "el resultado es", result
... finally:
... print "ejecutando la clausula finally"
...
>>> dividir(2, 1)
el resultado es 2
ejecutando la clausula finally
>>> dividir(2, 0)
77
>>> divide("2", "1")
Algunos objetos definen acciones de limpieza est�ndar que llevar a cabo cuando el
objeto no es m�s
necesitado, independientemente de que las operaciones sobre el objeto hayan sido
exitosas o no. Mir� el
siguiente ejemplo, que intenta abrir un archivo e imprimir su contenido en la
pantalla.:
El problema con este c�digo es que deja el archivo abierto por un periodo de tiempo
indeterminado luego
de que termine de ejecutarse. Esto no es un problema en scripts simples, pero puede
ser un problema en
aplicaciones m�s grandes. La declaraci�n with permite que objetos como archivos
sean usados de una
forma que asegure que siempre se los libera r�pido y en forma correcta.
with open("miarchivo.txt") as f:
for linea in f:
print linea
78
Clases
En terminolog�a de C++, todos los miembros de las clases (incluyendo los miembros
de datos), son
p�blicos, y todas las funciones miembro son virtuales. Como en Modula-3, no hay
atajos para hacer
referencia a los miembros del objeto desde sus m�todos: la funci�n m�todo se
declara con un primer
argumento expl�cito que representa al objeto, el cual se provee impl�citamente por
la llamada. Como en
Smalltalk, las clases mismas son objetos. Esto provee una sem�ntica para importar y
renombrar. A
diferencia de C++ y Modula-3, los tipos de datos integrados pueden usarse como
clases base para que el
usuario los extienda. Tambi�n, como en C++ pero a diferencia de Modula-3, la
mayor�a de los operadores
integrados con sintaxis especial (operadores aritm�ticos, de sub�ndice, etc.)
pueden ser redefinidos por
instancias de la clase.
(Sin haber una terminolog�a universalmente aceptada sobre clases, har� uso
ocasional de t�rminos de
Smalltalk y C++. Usar�a t�rminos de Modula-3, ya que su sem�ntica orientada a
objetos es m�s cercana a
Python que C++, pero no espero que muchos lectores hayan escuchado hablar de �l).
Los objetos tienen individualidad, y m�ltiples nombres (en muchos �mbitos) pueden
vincularse al mismo
objeto. Esto se conoce como aliasing en otros lenguajes. Normalmente no se aprecia
esto a primera vista
en Python, y puede ignorarse sin problemas cuando se maneja tipos b�sicos
inmutables (n�meros,
cadenas, tuplas). Sin embargo, el aliasing, o renombrado, tiene un efecto
posiblemente sorpresivo sobre
la sem�ntica de c�digo Python que involucra objetos mutables como listas,
diccionarios, y la mayor�a de
otros tipos. Esto se usa normalmente para beneficio del programa, ya que los
renombres funcionan como
punteros en algunos aspectos. Por ejemplo, pasar un objeto es barato ya que la
implementaci�n
solamente pasa el puntero; y si una funci�n modifica el objeto que fue pasado, el
que la llama ver� el
cambio; esto elimina la necesidad de tener dos formas diferentes de pasar
argumentos, como en Pascal.
Antes de ver clases, primero debo decirte algo acerca de las reglas de alcance de
Python. Las
definiciones de clases hacen unos lindos trucos con los espacios de nombres, y
necesit�s saber c�mo
funcionan los alcances y espacios de nombres para entender por completo c�mo es la
cosa. De paso, los
79
conocimientos en este tema son �tiles para cualquier programador Python avanzado.
Por cierto, yo uso la palabra atributo para cualquier cosa despu�s de un punto; por
ejemplo, en la
expresi�n z.real, real es un atributo del objeto z. Estrictamente hablando, las
referencias a nombres
en m�dulos son referencias a atributos: en la expresi�n modulo.funcion, modulo es
un objeto m�dulo
y funcion es un atributo de �ste. En este caso hay una relaci�n directa entre los
atributos del m�dulo y
los nombres globales definidos en el m�dulo: �est�n compartiendo el mismo espacio
de nombres! 4
�
el �mbito interno, donde se busca primero, contiene los nombres locales
�
los espacios de nombres de las funciones anexas, en las cuales se busca empezando
por el
alcance adjunto m�s cercano, contiene los nombres no locales pero tambi�n los no
globales
80
�
el �mbito ante�ltimo contiene los nombres globales del m�dulo actual
�
el alcance exterior (donde se busca al final) es el espacio de nombres que contiene
los
nombres incluidos
Si un nombre se declara como global, entonces todas las referencias y asignaciones
al mismo van directo
al alcance intermedio que contiene los nombres globales del m�dulo. De otra manera,
todas las variables
que se encuentren fuera del alcance interno son de s�lo lectura (un intento de
escribir a esas variables
simplemente crea una nueva variable en el alcance interno, dejando intacta la
variable externa del mismo
nombre).
Las clases introducen un poquito de sintaxis nueva, tres nuevos tipos de objetos y
algo de sem�ntica
nueva.
class Clase:
<declaraci�n-1>
.
.
.
<declaraci�n-N>
81
Las definiciones de clases, al igual que las definiciones de funciones
(instrucciones def) deben ejecutarse
antes de que tengan efecto alguno. (Es concebible poner una definici�n de clase
dentro de una rama de
un if, o dentro de una funci�n.)
Objetos clase
Los objetos clase soportan dos tipos de operaciones: hacer referencia a atributos e
instanciaci�n.
class MiClase:
i= 12345
def f(self):
return 'hola mundo'
x = MiClase()
...crea una nueva instancia de la clase y asigna este objeto a la variable local x.
82
especial llamado __init__(), de esta forma:
def __init__(self):
self.datos = []
x = MiClase()
Por supuesto, el m�todo __init__() puede tener argumentos para mayor flexibilidad.
En ese caso, los
argumentos que se pasen al operador de instanciaci�n de la clase van a parar al
m�todo __init__().
Por ejemplo,
>>> x = Complejo(3.0,-4.5)
>>> x.r, x.i
(3.0, -4.5)
Objetos instancia
Ahora, �Qu� podemos hacer con los objetos instancia? La �nica operaci�n que es
entendida por los
objetos instancia es la referencia de atributos. Hay dos tipos de nombres de
atributos v�lidos, atributos de
datos y m�todos.
x.contador = 1
while x.contador < 10:
x.contador = x.contador * 2
print x.contador
del x.contador
83
contrario.
Objetos m�todo
x.f()
xf = x.f
while True:
print xf()
�Qu� sucede exactamente cuando un m�todo es llamado? Deb�s haber notado que x.f()
fue llamado
m�s arriba sin ning�n argumento, a pesar de que la definici�n de funci�n de f()
especificaba un
argumento. �Qu� pas� con ese argumento? Seguramente Python levanta una excepci�n
cuando una
funci�n que requiere un argumento es llamada sin ninguno, a�n si el argumento no es
utilizado...
De hecho, tal vez hayas adivinado la respuesta: lo que tienen de especial los
m�todos es que el objeto es
pasado como el primer argumento de la funci�n. En nuestro ejemplo, la llamada x.f()
es exactamente
equivalente a MiClase.f(x). En general, llamar a un m�todo con una lista de n
argumentos es
equivalente a llamar a la funci�n correspondiente con una lista de argumentos que
es creada insertando el
objeto del m�todo antes del primer argumento.
84
Algunas observaciones
Los atributos de datos tienen preferencia sobre los m�todos con el mismo nombre;
para evitar conflictos
de nombre accidentales, que pueden causar errores dif�ciles de encontrar en
programas grandes, es
prudente usar alg�n tipo de convenci�n que minimice las posibilidades de dichos
conflictos. Algunas
convenciones pueden ser poner los nombres de m�todos con may�sculas, prefijar los
nombres de
atributos de datos con una peque�a cadena �nica (a lo mejor s�lo un gui�n bajo), o
usar verbos para los
m�todos y sustantivos para los atributos.
A los atributos de datos los pueden hacer referencia tanto los m�todos como los
usuarios ("clientes")
ordinarios de un objeto. En otras palabras, las clases no se usan para implementar
tipos de datos
abstractos puros. De hecho, en Python no hay nada que haga cumplir el ocultar
datos; todo se basa en
convenci�n. (Por otro lado, la implementaci�n de Python, escrita en C, puede
ocultar por completo detalles
de implementaci�n y el control de acceso a un objeto si es necesario; esto se puede
usar en extensiones
a Python escritas en C.)
Los clientes deben usar los atributos de datos con cuidado; �stos pueden romper
invariantes que
mantienen los m�todos si pisan los atributos de datos. Observ� que los clientes
pueden a�adir sus propios
atributos de datos a una instancia sin afectar la validez de sus m�todos, siempre y
cuando se eviten
conflictos de nombres; de nuevo, una convenci�n de nombres puede ahorrar un mont�n
de dolores de
cabeza.
No hay un atajo para hacer referencia a atributos de datos (�u otros m�todos!)
desde dentro de un m�todo.
A mi parecer, esto en realidad aumenta la legibilidad de los m�todos: no existe
posibilidad alguna de
confundir variables locales con variables de instancia cuando repasamos un m�todo.
class C:
f = f1
def g(self):
h=g
85
Ahora f, g y h son todos atributos de la clase C que hacen referencia a objetos
funci�n, y
consecuentemente son todos m�todos de las instancias de C; h siendo exactamente
equivalente a g.
Fijate que esta pr�ctica normalmente s�lo sirve para confundir al que lea un
programa.
Los m�todos pueden llamar a otros m�todos de la instancia usando el argumento self:
class Bolsa:
def __init__(self):
self.datos = []
def agregar(self, x):
self.datos.append(x)
Los m�todos pueden hacer referencia a nombres globales de la misma manera que lo
hacen las funciones
comunes. El alcance global asociado a un m�todo es el m�dulo que contiene la
definici�n de la clase. (La
clase misma nunca se usa como un alcance global.) Si bien es raro encontrar una
buena raz�n para usar
datos globales en un m�todo, hay muchos usos leg�timos del alcance global: por lo
menos, las funciones y
m�dulos importados en el alcance global pueden usarse por los m�todos, al igual que
las funciones y
clases definidas en �l. Habitualmente, la clase que contiene el m�todo est�
definida en este alcance
global, y en la siguiente secci�n veremos algunas buenas razones por las que un
m�todo querr�a hacer
referencia a su propia clase.
Todo valor es un objeto, y por lo tanto tiene una clase (tambi�n llamado su tipo).
�sta se almacena como
objeto.__class__.
Herencia
Por supuesto, una caracter�stica del lenguaje no ser�a digna del nombre "clase" si
no soportara herencia.
La sintaxis para una definici�n de clase derivada se ve as�:
class ClaseDerivada(ClaseBase):
<declaraci�n-1>
.
.
<declaraci�n-N>
class ClaseDerivada(modulo.ClaseBase):
86
La ejecuci�n de una definici�n de clase derivada procede de la misma forma que una
clase base. Cuando
el objeto clase se construye, se tiene en cuenta a la clase base. Esto se usa para
resolver referencias a
atributos: si un atributo solicitado no se encuentra en la clase, la b�squeda
contin�a por la clase base.
Esta regla se aplica recursivamente si la clase base misma deriva de alguna otra
clase.
Las clases derivadas pueden redefinir m�todos de su clase base. Como los m�todos no
tienen privilegios
especiales cuando llaman a otros m�todos del mismo objeto, un m�todo de la clase
base que llame a otro
m�todo definido en la misma clase base puede terminar llamando a un m�todo de la
clase derivada que lo
haya redefinido. (Para los programadores de C++: en Python todos los m�todos son en
efecto
virtuales.)
Un m�todo redefinido en una clase derivada puede de hecho querer extender en vez de
simplemente
reemplazar al m�todo de la clase base con el mismo nombre. Hay una manera simple de
llamar al m�todo
de la clase base directamente: simplemente llam�s a ClaseBase.metodo(self,
argumentos). En
ocasiones esto es �til para los clientes tambi�n. (Observ� que esto s�lo funciona
si la clase base es
accesible como CalseBase en el alcance global.)
�
Us� isinstance() para verificar el tipo de una instancia: isinstance(obj, int)
devuelve
True solo si obj.__class__ es int o alguna clase derivada de int.
�
Us� issubclass() para comprobar herencia de clase: issubclass(bool, int) da True
ya que bool es una subclase de int. Sin embargo, issubclass(unicode, str) devuelve
False porque unicode no es una subclase de str (solamente tienen un ancestro en
com�n,
basestring).
Herencia m�ltiple
Python tambi�n soporta una forma limitada de herencia m�ltiple. Una definici�n de
clase con m�ltiples
clases base se ve as�:
<declaraci�n-N>
87
(A algunos la b�squeda en anchura, o sea, buscar en Base2 y Base3 antes que en las
clases base de
Base1, les parece m�s natural. Sin embargo, para esto har�a falta que sepas si un
atributo en particular
de Base1 est� de hecho definido en Base1 o en alguna de sus clases base antes de
que puedas
entender las consecuencias de un conflicto de nombres con un atributo de Base2. La
regla de buscar
primero en profundidad no hace diferencias entre atributos directos o heredados de
Base1.)
Con las clases de estilo nuevo, se necesita el orden din�mico porque todos los
casos de herencia m�ltiple
exhiben una o m�s relaciones en diamante (cuando se puede llegar al menos a una de
las clases base
por distintos caminos desde la clase de m�s abajo). Por ejemplo, todas las clases
de nuevo estilo heredan
de object, por lo tanto cualquier caso de herencia m�ltiple provee m�s de un camino
para llegar a
object. Para que las clases base no sean accedidas m�s de una vez, el algoritmo
din�mico hace lineal
el orden de b�squeda de manera que se preserve el orden de izquierda a derecha
especificado en cada
clase, que se llame a cada clase base s�lo una vez, y que sea mon�tona (lo cual
significa que una clase
puede tener clases derivadas sin afectar el orden de precedencia de sus clases
bases). En conjunto, estas
propiedades hacen posible dise�ar clases confiables y extensibles con herencia
m�ltiple. Para m�s
detalles mir� http://www.python.org/download/releases/2.3/mro/.
Variables privadas
Las variables "privadas" de instancia que no pueden accederse excepto desde dentro
de un objeto, no
existen en Python. Sin embargo, hay una convenci�n que se sigue en la mayor�a del
c�digo Python: un
nombre prefijado con un gui�n bajo (por ejemplo, _spam) deber�a tratarse como una
parte no p�blica de la
API (m�s all� de que sea una funci�n, un m�todo, o un dato). Deber�a considerarse
un detalle de
implementaci�n y que est� sujeto a cambios sin aviso.
Ya que hay un caso de uso v�lido para los identificadores privados de clase (a
saber: colisi�n de nombres
con nombres definidos en las subclases), hay un soporte limitado para este
mecanismo. Cualquier
identificador con la forma __spam (al menos dos guiones bajos al principio, como
mucho un gui�n bajo al
final) es textualmente reemplazado por _nombredeclase__spam, donde nombredeclase es
el nombre
de clase actual al que se le sacan guiones bajos del comienzo (si los tuviera). Se
modifica el nombre del
identificador sin importar su posici�n sint�ctica, as� que puede ser usado para
definir instancias y variables
de clase privadas, m�todos, variables guardadas en globales, y a�n variables
guardadas en instancias
privadas de esta clase en instancias de otras clases. Puede ocurrir que se trunque
si el nombre
modificado queda con m�s de 255 caracteres. Fuera de las clases, o cuando el nombre
de clase consiste
solo en guiones bajos, no se modifican los nombres de identificadores.
Hay que aclarar que las reglas de modificaci�n de nombres est�n dise�adas
principalmente para evitar
accidentes; es posible acceder o modificar una variable que es considerada como
privada. Esto hasta
puede resultar �til en circunstancias especiales, tales como en el depurador.
88
Notar que el c�digo pasado a exec, a eval() o a execfile() no considera que el
nombre de clase de
la clase que invoca sea la clase actual; esto es similar al efecto de la sentencia
global, efecto que es de
similar manera restringido a c�digo que es compilado en conjunto. La misma
restricci�n aplica a
getattr(), setattr() y delattr(), as� como cuando se referencia a __dict__
directamente.
Cambalache
class Empleado:
pass
Alg�n c�digo Python que espera un tipo abstracto de datos en particular puede
frecuentemente recibir en
cambio una clase que emula los m�todos de aquel tipo de datos. Por ejemplo, si
ten�s una funci�n que
formatea algunos datos a partir de un objeto archivo, pod�s definir una clase con
m�todos read() y
readline() que obtengan los datos de alguna cadena en memoria intermedia, y pasarlo
como
argumento.
Las excepciones definidas por el usuario tambi�n son identificadas por clases.
Usando este mecanismo es
posible crear jerarqu�as extensibles de excepciones:
89
Una clase en una cl�usula except es compatible con una excepci�n si es de la misma
clase o una clase
base suya (pero no al rev�s, una cl�usula except listando una clase derivada no es
compatible con una
clase base). Por ejemplo, el siguiente c�digo imprimir� B, C, D en ese orden:
class B:
pass
class C(B):
pass
class D(C):
pass
Cuando se imprime un mensaje de error para una excepci�n sin atrapar, se imprime el
nombre de la clase
de la excepci�n, luego dos puntos y un espacio y finalmente la instancia convertida
a un string usando la
funci�n integrada str().
Iteradores
Es probable que hayas notado que la mayor�a de los objetos contenedores pueden ser
recorridos usando
una sentencia for:
>>> s = 'abc'
>>> it = iter(s)
>>> it
>>> it.next()
'a'
>>> it.next()
'b'
>>> it.next()
'c'
>>> it.next()
it.next()
StopIteration
m
a
p
91
s
Generadores
Los generadores son una simple y poderosa herramienta para crear iteradores. Se
escriben como
funciones regulares pero usan la sentencia yield cuando quieren devolver datos.
Cada vez que
next() es llamado, el generador contin�a desde donde dej� (y recuerda todos los
valores de datos y cual
sentencia fue ejecutada �ltima). Un ejemplo muestra que los generadores pueden ser
muy f�ciles de
crear:
o
g
Todo lo que puede ser hecho con generadores tambi�n puede ser hecho con iteradores
basados en
clases, como se describe en la secci�n anterior. Lo que hace que los generadores
sean tan compactos es
que los m�todos __iter__() y next() son creados autom�ticamente.
Expresiones generadoras
Algunos generadores simples pueden ser codificados concisamente como expresiones
usando una
sintaxis similar a las listas por comprensi�n pero con par�ntesis en vez de
corchetes. Estas expresiones
se utilizan en situaciones donde el generador es usado inmediatamente por una
funci�n que lo contiene.
Las expresiones generadoras son m�s compactas pero menos vers�tiles que
definiciones completas de
generadores, y tienden a utilizar menos memoria que las listas por comprensi�n
equivalentes.
Ejemplos:
92
>>> sum(i*i for i in range(10)) # suma de cuadrados
285
260
Excepto por un detalle. Los objetos m�dulo tienen un atributo secreto de solo
lectura llamado
__dict__ que devuelve el diccionario usado para implementar el espacio de nombres
del
m�dulo; el nombre __dict__ es un atributo, pero no es un nombre global. Obviamente,
esto
viola la abstracci�n de la implementaci�n de espacios de nombres, y debe ser
restringido a
cosas tales como depuradores post-mortem.
93
Peque�o paseo por la Biblioteca
Est�ndar
>>> import os
>>> os.system('time 0:02')
'C:\\Python26'
>>> os.chdir('/server/accesslogs')
Las funciones integradas dir() y help() son �tiles como ayudas interactivas para
trabajar con
m�dulos grandes como os:
>>> import os
>>> dir(os)
>>> help(os)
Comodines de archivos
El m�dulo glob provee una funci�n para hacer listas de archivos a partir de
b�squedas con comodines
en directorios:
>>> import glob
>>> glob.glob('*.py')
94
Argumentos de linea de �rdenes
El m�dulo sys tambi�n tiene atributos para stdin, stdout, y stderr. Este �ltimo es
�til para emitir mensajes
de alerta y error para que se vean incluso cuando se haya redireccionado stdout:
>>> import re
'gato en el sombrero'
Cuando se necesita algo m�s sencillo solamente, se prefieren los m�todos de las
cadenas porque son
m�s f�ciles de leer y depurar.
95
Matem�tica
0.70710678118654757
>>> math.log(1024, 2)
'manzana'
0.17970987693706186
Acceso a Internet
Hay varios m�dulos para acceder a internet y procesar sus protocolos. Dos de los
m�s simples son
urllib2 para traer data de URLs y smtplib para mandar correos:
...
... """)
96
>>> server.quit()
Fechas y tiempos
El m�dulo datetime ofrece clases para manejar fechas y tiempos tanto de manera
simple como
compleja. Aunque se soporta aritm�tica sobre fechas y tiempos, el foco de la
implementaci�n es en la
extracci�n eficiente de partes para manejarlas o formatear la salida. El m�dulo
tambi�n soporta objetos
que son conscientes de la zona horaria.
Compresi�n de datos
Los formatos para archivar y comprimir datos se soportan directamente con los
m�dulos: zlib, gzip,
bz2, zipfile y tarfile.
41
>>> t = zlib.compress(s)
>>> len(t)
37
97
>>> zlib.decompress(t)
>>> zlib.crc32(s)
226805979
Medici�n de rendimiento
0.57535828626024577
0.54962537085770791
En contraste con el fino nivel de granularidad del m�dulo timeit, los m�dulos
profile y pstats
proveen herramientas para identificar secciones cr�ticas de tiempo en bloques de
c�digo m�s grandes.
Control de calidad
Una forma para desarrollar software de alta calidad es escribir pruebas para cada
funci�n mientras se la
desarrolla, y correr esas pruebas frecuentemente durante el proceso de desarrollo.
El m�dulo doctest provee una herramienta para revisar un m�dulo y validar las
pruebas integradas en
las cadenas de documentaci�n (o docstring) del programa. La construcci�n de las
pruebas es tan sencillo
como cortar y pegar una ejecuci�n t�pica junto con sus resultados en los
docstrings. Esto mejora la
documentaci�n al proveer al usuario un ejemplo y permite que el m�dulo doctest se
asegure que el
c�digo permanece fiel a la documentaci�n:
def promedio(valores):
40.0
"""
return sum(valores, 0.0) / len(valores)
98
import doctest
El m�dulo unittest necesita m�s esfuerzo que el m�dulo doctest, pero permite que se
mantenga en
un archivo separado un conjunto m�s comprensivo de pruebas:
import unittest
class TestFuncionesEstadisticas(unittest.TestCase):
def test_promedio(self):
self.assertEqual(promedio([20, 30, 70]), 40.0)
self.assertEqual(round(promedio([1, 5, 7]), 1), 4.3)
self.assertRaises(ZeroDivisionError, promedio, [])
self.assertRaises(TypeError, promedio, 20, 30, 70)
�
Los m�dulos xmlrpclib y SimpleXMLRPCServer hacen que implementar llamadas a
procedimientos remotos sea una tarea trivial. A pesar de los nombres de los
m�dulos, no se
necesita conocimiento directo o manejo de XML.
�
El paquete email es una biblioteca para manejar mensajes de mail, incluyendo MIME y
otros
mensajes basados en RFC 2822. Al contrario de smtplib y poplib que en realidad
env�an y
reciben mensajes, el paquete email tiene un conjunto de herramientas completo para
construir y
decodificar estructuras complejas de mensajes (incluyendo adjuntos) y para
implementar
protocolos de cabecera y codificaci�n de Internet.
�
Los paquetes xml.dom y xml.sax proveen un robusto soporte para analizar este
popular
formato de intercambio de datos. Asimismo, el m�dulo csv soporta lecturas y
escrituras directas
en un formato com�n de base de datos. Juntos, estos m�dulos y paquetes simplifican
enormemente el intercambio de datos entre aplicaciones Python y otras herramientas.
�
Se soporta la internacionalizaci�n a trav�s de varios m�dulos, incluyendo gettext,
locale, y el
paquete codecs.
99
Peque�o paseo por la Biblioteca
Est�ndar - Parte II
Este segundo paseo cubre m�dulos m�s avanzados que facilitan necesidades de
programaci�n
complejas. Estos m�dulos raramente se usan en scripts cortos.
Formato de salida
El m�dulo repr provee una versi�n de repr() ajustada para mostrar contenedores
grandes o
profundamente anidados, en forma abreviada:
[[[['negro', 'turquesa'],
'blanco',
['verde', 'rojo']],
[['magenta', 'amarillo'],
'azul']]]
El m�dulo textwrap formatea p�rrafos de texto para que quepan dentro de cierto
ancho de pantalla:
'Spanish_Argentina.1252'
'1.234.567'
'$1.234.567,80'
Plantillas
El m�dulo string incluye una clase vers�til Template (plantilla) con una sintaxis
simplificada apta para
ser editada por usuarios finales. Esto permite que los usuarios personalicen sus
aplicaciones sin
necesidad de modificar la aplicaci�n en s�.
. . .
KeyError: 'owner'
>>> t.safe_substitute(d)
101
Las subclases de Template pueden especificar un delimitador propio. Por ejemplo,
una utilidad de
renombrado por lotes para un visualizador de fotos puede escoger usar signos de
porcentaje para los
marcadores tales como la fecha actual, el n�mero de secuencia de la imagen, o el
formato de archivo:
>>> t = BatchRename(fmt)
>>> date = time.strftime('%d%b%y')
>>> for i, filename in enumerate(photofiles):
... base, ext = os.path.splitext(filename)
... newname = t.substitute(d=date, n=i, f=ext)
... print '{0} --> {1}'.format(filename, newname)
...
Las plantillas tambi�n pueden ser usadas para separar la l�gica del programa de los
detalles de m�ltiples
formatos de salida. Esto permite sustituir plantillas espec�ficas para archivos
XML, reportes en texto plano,
y reportes web en HTML.
El m�dulo struct provee las funciones pack() y unpack() para trabajar con formatos
de registros
binarios de longitud variable. El siguiente ejemplo muestra c�mo recorrer la
informaci�n de encabezado en
un archivo ZIP sin usar el m�dulo zipfile. Los c�digos "H" e "I" representan
n�meros sin signo de
dos y cuatro bytes respectivamente. El "<" indica que son de tama�o est�ndar y los
bytes tienen
ordenamiento little-endian:
import struct
inicio = 0
for i in range(3): # mostrar los 3 primeros encabezados
inicio += 14
campos = struct.unpack('<IIIHH', datos[inicio:inicio+16])
crc32, tam_comp, tam_descomp, tam_nomarch, tam_extra = fields
102
inicio += 16
nomarch = datos[inicio:inicio+tam_nomarch]
inicio += tam_nomarch
extra = datos[inicio:inicio+tam_extra]
print nomarch, hex(crc32), tam_comp, tam_descomp
Multi-hilos
El c�digo siguiente muestra c�mo el m�dulo de alto nivel threading puede ejecutar
tareas en segundo
plano mientras el programa principal contin�a su ejecuci�n:
class AsyncZip(threading.Thread):
def run(self):
f = zipfile.ZipFile(self.arch_sal, 'w', zipfile.ZIP_DEFLATED)
f.write(self.arch_ent)
f.close()
print u'Termin� zip en segundo plano de: ', self.arch_ent
print u'El programa principal esper� hasta que el segundo plano terminara.'
103
A�n cuando esas herramientas son poderosas, peque�os errores de dise�o pueden
resultar en problemas
dif�ciles de reproducir. La forma preferida de coordinar tareas es concentrar todos
los accesos a un
recurso en un �nico hilo y despu�s usar el m�dulo Queue para alimentar dicho hilo
con pedidos desde
otros hilos. Las aplicaciones que usan objetos Queue.Queue para comunicaci�n y
coordinaci�n entre
hilos son m�s f�ciles de dise�ar, m�s legibles, y m�s confiables.
Registrando
import logging
logging.debug(u'Informaci�n de depuraci�n')
logging.info(u'Mensaje informativo')
logging.warning(u'Atenci�n: archivo de configuraci�n %s no se encuentra',
'server.conf')
logging.error(u'Ocurri� un error')
logging.critical(u'Error cr�tico -- cerrando')
Referencias d�biles
104
El m�dulo weakref provee herramientas para seguimiento de objetos que no crean una
referencia.
Cuando el objeto no se necesita m�s, es eliminado autom�ticamente de una tabla de
referencias d�biles y
se dispara una retrollamada (callback). Com�nmente se usa para mantener una cache
de objetos que son
caros de crear:
>>> d = weakref.WeakValueDictionary()
10
KeyError: 'primaria'
El m�dulo array provee un objeto array() (vector) que es como una lista que
almacena s�lo datos
homog�neos y de una manera m�s compacta. Los ejemplos a continuaci�n muestran un
vector de
n�meros guardados como dos n�meros binarios sin signo de dos bytes (c�digo de tipo
"H") en lugar de
los 16 bytes por elemento habituales en listas de objetos int de Python:
26932
>>> a[1:3]
El m�dulo collections provee un objeto deque() que es como una lista m�s r�pida
para agregar y
quitar elementos por el lado izquierdo pero b�squedas m�s lentas por el medio.
Estos objetos son
105
adecuados para implementar colas y �rboles de b�squeda a lo ancho:
Realizando tarea1
no_visitado = deque([nodo_inicial])
def busqueda_a_lo_ancho(no_visitado):
nodo = no_visitado.popleft()
for m in gen_moves(nodo):
if is_goal(m):
return m
no_visitado.append(m)
[(100, 'perl'), (200, 'tcl'), (300, 'ruby'), (400, 'lua'), (500, 'python')]
El m�dulo heapq provee funciones para implementar heaps basados en listas comunes.
El menor valor
ingresado se mantiene en la posici�n cero. Esto es �til para aplicaciones que
acceden a menudo al
elemento m�s chico pero no quieren hacer un orden completo de la lista:
[-5, 0, 1]
El m�dulo decimal provee un tipo de dato Decimal para soportar aritm�tica de punto
flotante decimal.
Comparado con float, la implementaci�n de punto flotante binario incluida, la clase
es muy �til
especialmente para:
Decimal('0.7350')
0.73499999999999999
Decimal('0.00')
0.09999999999999995
True
>>> sum([0.1]*10) == 1.0
False
El m�dulo decimal provee aritm�tica con tanta precisi�n como haga falta:
>>> getcontext().prec = 36
>>> Decimal(1) / Decimal(7)
Decimal('0.142857142857142857142857142857142857')
107
�Y ahora qu�?
Leer este tutorial probablemente reforz� tu inter�s por usar Python, deber�as estar
ansioso por aplicar
Python a la resoluci�n de tus problemas reales. �A d�nde deber�as ir para aprender
m�s?
Este tutorial forma parte del juego de documentaci�n de Python. Algunos otros
documentos que
encontrar�s en este juego son:
�
library-index:
Deber�as hojear este manual, que tiene material de referencia completo (si bien
breve) sobre tipos,
funciones y m�dulos de la biblioteca est�ndar. La distribuci�n de Python est�ndar
incluye un
mont�n de c�digo adicional. Hay m�dulos para leer archivos de correo de Unix,
obtener
documentos v�a HTTP, generar n�meros aleatorios, interpretar opciones de l�nea de
comandos,
escribir programas CGI, comprimir datos, y muchas otras tareas. Un vistazo por la
Referencia de
Biblioteca te dar� una idea de lo que hay disponible.
�
install-index explica c�mo instalar m�dulos externos escritos por otros usuarios de
Python.
�
reference-index: Una descripci�n en detalle de la sintaxis y sem�ntica de Python.
Es una lectura
pesada, pero �til como gu�a completa al lenguaje en si.
M�s recursos sobre Python:
�
http://www.python.org: El sitio web principal sobre Python. Contiene c�digo,
documentaci�n, y
referencias a p�ginas relacionadas con Python en la Web. Este sitio web tiene
copias espejo en
varios lugares del mundo c�mo Europa, Jap�n y Australia; una copia espejo puede
funcionar m�s
r�pido que el sitio principal, dependiendo de tu ubicaci�n geogr�fica.
�
http://docs.python.org: Acceso r�pido a la documentaci�n de Python.
�
http://pypi.python.org: El �ndice de Paquetes de Python, antes tambi�n apodado "El
Negocio de
Quesos", es un listado de m�dulos de Python disponibles para descargar hechos por
otros
usuarios. Cu�ndo comiences a publicar c�digo, puedes registrarlo aqu� as� los dem�s
pueden
encontrarlo.
�
http://aspn.activestate.com/ASPN/Python/Cookbook/: El Recetario de Python es una
colecci�n de
tama�o considerable de ejemplos de c�digo, m�dulos m�s grandes, y programas �tiles.
Las
contribuciones particularmente notorias est�n recolectadas en un libro tambi�n
titulado Recetario
de Python (O'Reilly & Associates, ISBN 0-596-00797-3.)
Para preguntas relacionadas con Python y reportes de problemas puedes escribir al
grupo de noticias
comp.lang.python, o enviarlas a la lista de correo que hay en python-
list@python.org. El grupo de noticias
y la lista de correo est�n interconectadas, por lo que los mensajes enviados a uno
ser�n retransmitidos al
otro. Hay alrededor de 120 mensajes diarios (con picos de hasta varios cientos),
haciendo (y
respondiendo) preguntas, sugiriendo nuevas caracter�sticas, y anunciando nuevos
m�dulos. Antes de
escribir, aseg�rate de haber revisado la lista de Preguntas Frecuentes (tambi�n
llamado el FAQ), o
buscalo en el directorio Misc/ de la distribuci�n de c�digo fuente de Python. Hay
archivos de la lista de
correo disponibles en http://mail.python.org/pipermail/. El FAQ responde a muchas
de las preguntas que
aparecen una y otra vez, y puede que ya contenga la soluci�n a tu problema.
108
Edici�n de entrada interactiva y
sustituci�n de historial
Este cap�tulo no documenta las capacidades de edici�n del paquete PythonWin de Mark
Hammond, ni del
entorno IDLE basado en Tk que se distribuye con Python. El historial de l�nea de
comandos que funciona
en pantallas de DOS en NT y algunas otras variantes de DOS y Windows es tambi�n una
criatura
diferente.
Edici�n de l�nea
Sustituci�n de historial
nombre-de-tecla: nombre-de-funci�n
...o
"cadena": nombre-de-funci�n
Por ejemplo:
Observa que la asociaci�n por omisi�n para la tecla Tab en Python es insertar un
caracter Tab
(tabulaci�n horizontal) en vez de la funci�n por defecto de Readline de completar
nombres de archivo. Si
insistes, puedes redefinir esto poniendo
Tab: complete
110
resultante. Ten� en cuenta que esto puede ejecutar c�digo definido por la
aplicaci�n si un objeto con un
m�todo __getattr__() forma parte de la expresi�n.
Un archivo de inicializaci�n con m�s capacidades podr�a ser como este ejemplo.
Observ� que �ste borra
los nombres que crea una vez que no se necesitan m�s; esto se hace debido a que el
archivo de
inicializaci�n se ejecuta en el mismo espacio de nombres que los comandos
interactivos, y borrar los
nombres evita que se produzcan efectos colaterales en el entorno interactivo. Tal
vez te resulte c�modo
mantener algunos de los m�dulos importados, tales como os, que usualmente acaban
siendo necesarios
en la mayor�a de las sesiones con el int�rprete.
import atexit
import os
import readline
import rlcompleter
historyPath = os.path.expanduser("~/.pyhistory")
def save_history(historyPath=historyPath):
import readline
readline.write_history_file(historyPath)
if os.path.exists(historyPath):
readline.read_history_file(historyPath)
atexit.register(save_history)
del os, atexit, readline, rlcompleter, save_history, historyPath
111
completado podr�a usar la tabla de s�mbolos del int�rprete. Un comando para
verificar (o incluso sugerir)
coincidencia de par�ntesis, comillas, etc. tambi�n ser�a �til.
Un int�rprete interactivo mejorado alternativo que est� dando vueltas desde hace
rato es IPython, que
ofrece completado por tab, exploraci�n de objetos, y administraci�n avanzada del
historial. Tambi�n
puede ser configurado en profundidad, e integrarse en otras aplicaciones. Otro
entorno interactivo
mejorado similar es bpython.
112
Aritm�tica de Punto Flotante:
Problemas y Limitaciones
0.125
0.001
...tiene el valor 0/2 + 0/4 + 1/8. Estas dos fracciones tienen valores id�nticos,
la �nica diferencia real es
que la primera est� escrita en notaci�n fraccional en base 10 y la segunda en base
2.
El problema es m�s f�cil de entender primero en base 10. Consider� la fracci�n 1/3.
Pod�s aproximarla
como una fracci�n de base 10
...o, mejor,
...o, mejor,
0.333
...y as�. No importa cuantos d�gitos desees escribir, el resultado nunca ser�
exactamente 1/3, pero ser�
una aproximaci�n cada vez mejor de 1/3.
0.0001100110011001100110011001100110011001100110011...
Fren� en cualquier n�mero finito de bits, y tendr�s una aproximaci�n. Es por esto
que ves cosas como:
>>> 0.1
0.10000000000000001
En la mayor�a de las m�quinas de hoy en d�a, eso es lo que ver�s si ingres�s 0.1 en
un prompt de Python.
Quiz�s no, sin embargo, porque la cantidad de bits usados por el hardware para
almacenar valores de
113
punto flotante puede variar en las distintas m�quinas, y Python s�lo muestra una
aproximaci�n del valor
decimal verdadero de la aproximaci�n binaria guardada por la m�quina. En la mayor�a
de las m�quinas, si
Python fuera a mostrar el verdadero valor decimal de la aproximaci�n almacenada por
0.1, tendr�a que
mostrar sin embargo
>>> 0.1
0.1000000000000000055511151231257827021181583404541015625
El prompt de Python usa la funci�n integrada repr() para obtener una versi�n en
cadena de caracteres
de todo lo que muestra. Para flotantes, repr(float) redondea el valor decimal
verdadero a 17 d�gitos
significativos, dando
0.10000000000000001
Not� que esta es la verdadera naturaleza del punto flotante binario: no es un error
de Python, y tampoco
es un error en tu c�digo. Ver�s lo mismo en todos los lenguajes que soportan la
aritm�tica de punto
flotante de tu hardware (a pesar de que en algunos lenguajes por omisi�n no
muestren la diferencia, o no
lo hagan en todos los modos de salida).
Es importante darse cuenta de que esto es, realmente, una ilusi�n: el valor en la
m�quina no es
exactamente 1/10, simplemente est�s redondeando el valor que se muestra del valor
verdadero de la
m�quina.
>>> 0.1
0.10000000000000001
...quiz�s est�s tentado de usar la funci�n round() para recortar el resultado al
d�gito que esperabas.
Pero es lo mismo:
>>> round(0.1, 1)
0.10000000000000001
El problema es que el valor de punto flotante binario almacenado para "0.1" ya era
la mejor aproximaci�n
binaria posible de 1/10, de manera que intentar redondearla nuevamente no puede
mejorarla: ya era la
mejor posible.
Otra consecuencia es que como 0.1 no es exactamente 1/10, sumar diez valores de 0.1
quiz�s tampoco
d� exactamente 1.0:
114
>>> suma = 0.0
>>> for i in range(10):
... suma += 0.1
...
>>> suma
0.99999999999999989
Como dice cerca del final, "no hay respuestas f�ciles". A pesar de eso, �no le
tengas mucho miedo al
punto flotante! Los errores en las operaciones flotantes de Python se heredan del
hardware de punto
flotante, y en la mayor�a de las m�quinas est�n en el orden de no m�s de una 1
parte en 2**53 por
operaci�n. Eso es m�s que adecuado para la mayor�a de las tareas, pero necesit�s
tener en cuenta que
no es aritm�tica decimal, y que cada operaci�n de punto flotante sufre un nuevo
error de redondeo.
Error de Representaci�n
>>> 0.1
0.10000000000000001
�Por qu� es eso? 1/10 no es representable exactamente como una fracci�n binaria.
Casi todas las
m�quinas de hoy en d�a (Noviembre del 2000) usan aritm�tica de punto flotante IEEE-
754, y casi todas las
plataformas mapean los flotantes de Python al "doble precisi�n" de IEEE-754. Estos
"dobles" tienen 53
bits de precisi�n, por lo tanto en la entrada la computadora intenta convertir 0.1
a la fracci�n m�s cercana
que puede de la forma J/2***N* donde J es un entero que contiene exactamente 53
bits. Reescribiendo
1 / 10 ~= J / (2**N)
...como
115
J ~= 2**N / 10
...y recordando que J tiene exactamente 53 bits (es >= 2**52 pero < 2**53), el
mejor valor para N es
56:
>>> 2**52
4503599627370496L
>>> 2**53
9007199254740992L
>>> 2**56/10
7205759403792793L
O sea, 56 es el �nico valor para N que deja J con exactamente 53 bits. El mejor
valor posible para J es
entonces el cociente redondeado:
6L
>>> q+1
7205759403792794L
Por lo tanto la mejor aproximaci�n a 1/10 en doble precisi�n 754 es eso sobre
2**56, o
7205759403792794 / 72057594037927936
Not� que como lo redondeamos, esto es un poquito m�s grande que 1/10; si no lo
hubi�ramos
redondeado, el cociente hubiese sido un poquito menor que 1/10. �Pero no hay caso
en que sea
exactamente 1/10!
>>> .1 * 2**56
7205759403792794.0
Si multiplicamos esa fracci�n por 10**30, podemos ver el valor (truncado) de sus 30
d�gitos m�s
significativos:
100000000000000005551115123125L
116