Adem�s de la sentencia while, reci�n presentada, Python conoce las sentencias de control de flujo comunes de otros lenguajes, aunque con sabor propio.
Quiz� la mejor conocida de las construcciones es if (si). Por ejemplo:
>>> x = int(raw_input("Introduce un n�mero: ")) >>> if x < 0: ... x = 0 ... print 'Negativo cambiado a cero' ... elif x == 0: ... print 'Cero' ... elif x == 1: ... print 'Uno' ... else: ... print 'M�s' ...
Puede haber cero o m�s partes elif y la parte else (si no) es opcional. La palabra clave `elif' es una abreviatura de `else if' y evita el sagrado excesivo. Una secuencia if ... elif ... elif ... es el sustituto de las sentencias switch o case de otros lenguajes.
La construcci�n for (para) es un poco diferente a lo acostumbrado en C o Pascal. En lugar de recorrer siempre una progresi�n aritm�tica (como en Pascal) o dejar al programador total libertad de elecci�n de inicializaci�n, comprobaci�n y salto de paso (como en C), el for de Python recorre los elementos de una secuencia (por ejemplo, una lista o cadena), en el orden en que aparecen en la secuencia. Por ejemplo:
>>> # Medir algunas cadenas: ... a = ['gato', 'ventana', 'defenestrar'] >>> for x in a: ... print x, len(x) ... gato 4 ventana 7 defenestrar 11
No es aconsejable modificar la secuencia que se est� recorriendo (lo que s�lo puede ocurrir en secuencias mutables, por ejemplo, listas). Si se necesita modificar la lista recorrida, por ejemplo, para duplicar los elementos, hay que recorrer una copia. La notaci�n de corte hace esto muy c�modo.
>>> for x in a[:]: # hacer una copia por corte de la lista entera ... if len(x) > 7: a.insert(0, x) ... >>> a ['defenestrar', 'gato', 'ventana', 'defenestrar']
Si lo que necesitas es recorrer una secuencia de n�meros, la funci�n interna range() viene de perlas. Genera listas con progresiones aritm�ticas, por ejemplo:
>>> range(10) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
El punto final indicado nunca es parte de la lista generada, as� que
range(10)
genera una lista de 10 valores, justo los �ndices legales
de los elementos de una secuencia de longitud 10. Es posible hacer que el
rango arranque en otro n�mero o especificar un incremento diferente (incluso
negativo). Este incremento se llama paso (step):
>>> range(5, 10) [5, 6, 7, 8, 9] >>> range(0, 10, 3) [0, 3, 6, 9] >>> range(-10, -100, -30) [-10, -40, -70]
Para recorrer los �ndices de una secuencia, combina range() y len() de este modo:
>>> a = ['Cinco', 'lobitos', 'tiene', 'la', 'loba'] >>> for i in range(len(a)): ... print i, a[i] ... 0 Cinco 1 lobitos 2 tiene 3 la 4 loba
La sentencia break (romper), como en C, salta del bucle for o while en curso m�s interno.
La sentencia continue (continuar), tambi�n un pr�stamo de C, hace que siga la siguiente iteraci�n del bucle.
Las construcciones de bucle pueden tener una cl�usula else
. �sta se
ejecuta, si existe, cuando se termina el bucle por agotamiento de la lista
(con for) o cuando la condici�n se hace falsa (con
while), pero no cuando se termina el bucle con
break. Para aclarar esto
�ltimo, valga un ejemplo, que busca n�meros primos:
>>> for n in range(2, 10): ... for x in range(2, n): ... if n % x == 0: ... print n, '=', x, '*', n/x ... break ... else: ... print n, 'es primo' ... 2 es primo 3 es primo 4 = 2 * 2 5 es primo 6 = 2 * 3 7 es primo 8 = 2 * 4 9 = 3 * 3
La sentencia pass no hace nada. Se puede utilizar cuando hace falta una sentencia sint�cticamente pero no hace falta hacer nada. Por ejemplo:
>>> while 1: ... pass # Espera activamente una interrupci�n de teclado ...
Se puede crear una funci�n que escriba la serie de Fibonacci hasta un l�mite superior arbitrario:
>>> def fib(n): # escribir la serie Fibonacci hasta n ... "escribir la serie Fibonacci hasta n" ... a, b = 0, 1 ... while b < n: ... print b, ... a, b = b, a+b ... >>> # Y ahora llamamos a la funci�n reci�n definida: ... fib(2000) 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597
La palabra clave def introduce una definici�n de funci�n. Debe ir seguida del nombre de la funci�n y la lista entre par�ntesis de los par�metros formales. Las sentencias que forman el cuerpo de la funci�n empiezan en la siguiente l�nea y deben ir sangradas. La primera sentencia del cuerpo de la funci�n puede ser una constante de cadena: esta cadena es la documentaci�n de la funci�n o docstring.
Existen herramientas para producir autom�ticamente documentaci�n impresa/electr�nica o permitir al usuario navegar por el c�digo interactivamente. Es una buena pr�ctica incluir documentaci�n en el c�digo que escribas, as� que intenta hacer de ello un h�bito.
La ejecuci�n de una funci�n introduce una tabla de s�mbolos nueva para las variables locales de Python. En concreto, todas las asignaciones de variables de una funci�n almacenan el valor en la tabla de s�mbolos local; por lo que las referencias a variables primero miran en la tabla de s�mbolos local, luego en la tabla de s�mbolos global y, por �ltimo, en la tabla de nombres internos. Por ello no se puede asignar un valor a una variable global dentro de una funci�n (salvo que est� mencionada en una sentencia global), pero se puede hacer referencia a ellas.
Los par�metros reales (argumentos) de una llamada a una funci�n se introducen en la tabla de s�mbolos local de la funci�n aludida al llamarla: los argumentos se pasan por valor (en donde el valor siempre es una referencia a un objeto, no el valor del objeto4.1. Cuando una funci�n llama a otra funci�n, se crea una tabla de s�mbolos locales nueva para esa llamada.
Una definici�n de funci�n introduce el nombre de la funci�n en la tabla de s�mbolos vigente. El valor del nombre de la funci�n tiene un tipo reconocido por el int�rprete como funci�n definida por el usuario. Se puede asignar este valor a otro nombre y usar �ste, a su vez, como funci�n que es. Esto sirve de mecanismo de renombrado gen�rico:
>>> fib <function object at 10042ed0> >>> f = fib >>> f(100) 1 1 2 3 5 8 13 21 34 55 89
Se puede objetar que fib
no es una funci�n, sino un procedimiento. En
Python, como en C, los procedimientos son simplemente funciones que no
devuelven ning�n valor. De hecho, hablando t�cnicamente, los
procedimientos s� devuelven un valor, s�lo que bastante aburrido.
Este valor se llama None
(es un nombre interno).
El int�rprete suele omitir la escritura del valor de None
,
si es el �nico valor que se fuera a escribir. Se puede
ver si realmente lo deseas:
>>> print fib(0) None
Resulta simple escribir una funci�n que devuelva una lista de los n�meros de la serie de Fibonacci, en lugar de mostrarla:
>>> def fib2(n): # Devolver la serie de Fibonacci hasta n ... "Devolver una lista con los n�meros de la serie de Fibonacci hasta n" ... resultado = [] ... a, b = 0, 1 ... while b < n: ... resultado.append(b) # ver m�s abajo ... a, b = b, a+b ... return resultado ... >>> f100 = fib2(100) # llamarlo >>> f100 # escribir el resultado [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
resultado.append(b)
llama a un m�todo del objeto
lista resultado
. Un m�todo es una funci�n que `pertenece' a un objeto
y se llama obj.nombreM�todo
, donde obj
es un objeto (que
puede resultar de una expresi�n) y nombreM�todo
es el nombre del
m�todo definido por el tipo del objeto. Los m�todos de diferentes tipos pueden
tener el mismo nombre sin ambig�edad. Es posible definir tus propios tipos de
objetos y m�todos, utilizando clases, seg�n se discute m�s adelante en
esta gu�a. El m�todo append() (empalmar), mostrado en el ejemplo, est�
definido para objetos lista: A�ade un elemento nuevo al final de la lista. En
este ejemplo es equivalente a "resultado = resultado + [b]", pero m�s
eficaz.
Tambi�n es posible definir funciones con un n�mero variable de argumentos. Existen tres formas, que se pueden combinar.
Es la forma m�s �til de especificar un valor por omisi�n para uno o m�s de los argumentos. Esto crea una funci�n a la que se puede llamar con menos argumentos de los que tiene definidos, por ejemplo:
def confirmar(indicador, intentos=4, queja='�O s� o no!'): while 1: respuesta = raw_input(indicador) if respuesta in ('s', 'si', 's�'): return 1 if respuesta in ('n', 'no', 'nanay', 'nasti'): return 0 intentos = intentos - 1 if intentos < 0: raise IOError, 'Usuario rechazado' print queja
Se puede llamar a esta funci�n as�: confirmar('�Quiere salir?')
o
as�: confirmar('�Desea borrar el fichero?', 2)
.
Los valores por omisi�n se eval�an en el instante de definici�n de la funci�n en el �mbito de definici�n, as�:
i = 5 def f(arg = i): print arg i = 6 f()
mostrar� 5
.
Aviso importante: El argumento por omisi�n se eval�a una sola vez. Esto lleva a diferentes resultados cuando el valor por omisi�n es un objeto mutable, tal como una lista o diccionario. Por ejemplo, la siguiente funci�n acumula los argumentos que se le pasan en sucesivas llamadas:
def f(a, l = []): l.append(a) return l print f(1) print f(2) print f(3)
Esto presenta:
[1] [1, 2] [1, 2, 3]
Si no se desea que el valor por omisi�n sea compartido por las sucesivas llamadas, se puede escribir la funci�n de este modo:
def f(a, l = None): if l is None: l = [] l.append(a) return l
Tambi�n se puede llamar a una funci�n utilizando la forma "clave = valor". Por ejemplo, la siguiente funci�n:
def loro(tension, estado='tieso', accion='voom', tipo='Azul noruego'): print "-- Este loro no podr�a", accion, print "aunque le aplicara", tension, "voltios." print "-- Bello plumaje, el", tipo print "-- �Est�", estado, "!"
puede invocarse de estas maneras:
loro(1000) loro(accion = 'VOOOOOM', tension = 1000000) loro('mil', estado = 'criando malvas') loro('un mill�n de', 'desprovisto de vida', 'saltar')
pero las siguientes llamadas ser�an todas incorrectas:
loro() # falta un argumento obligatorio loro(tension=5.0, 'muerto') # argumento clave seguido por argumento no-clave loro(110, tension=220) # valor de argumento duplicado loro(actor='John Cleese') # clave desconocida
En general, una lista de argumentos debe tener argumentos posicionales seguidos por argumentos clave, donde las claves se seleccionan de los nombres de los par�metros formales. No importa si un par�metro formal tiene valor por omisi�n o no. Ning�n argumento debe recibir valor m�s de una vez (los nombres de par�metros formales correspondientes a argumentos posicionales no se pueden usar como claves en la misma llamada). He aqu� un ejemplo que falla por culpa de esta restricci�n:
>>> def function(a): ... pass ... >>> function(0, a=0) Traceback (innermost last): File "<stdin>", line 1, in ? TypeError: keyword parameter redefined
Cuando el �ltimo par�metro formal tiene la forma **nombre
recibe
un diccionario que contiene todos los argumentos clave cuya clave no se
corresponde con ning�n par�metro formal.
Esto se puede combinar con un par�metro formal de la
forma *nombre
(descrito en la siguiente subsecci�n) que recibe una
tupla que contiene los argumentos posicionales que exceden la lista de
par�metros formales (*nombre
debe aparecer antes de **nombre
).
Por ejemplo, si definimos una funci�n como �sta:
def queseria(clase, *argumentos, **claves): print "-- �Tiene", clase, '?' print "-- Lo siento, no nos queda", clase for arg in argumentos: print arg print '-'*40 for kw in claves.keys(): print kw, ':', claves[kw]
se puede invocar de estas maneras:
queseria('Limburger', "Chorrea mucho, se�or.", "Chorrea mucho, much�simo.", cliente='John Cleese', tendero='Michael Palin', sketch='Sketch de la queser�a')
Y mostrar�a:
-- �Tiene Limburger ? -- Lo siento, no nos queda Limburger Chorrea mucho, se�or. Chorrea mucho, much�simo. ---------------------------------------- cliente : John Cleese tendero : Michael Palin sketch : Sketch de la queser�a
Finalmente, la opci�n menos frecuente es especificar que una funci�n puede llamarse con un n�mero arbitrario de argumentos. Estos argumentos se agrupar�n en una tupla. Antes del n�mero variable de argumentos puede haber cero o m�s argumentos normales.
def fprintf(file, formato, *args): file.write(formato % args)
A petici�n popular, se han a�adido a Python algunas caracter�sticas com�nmente halladas en los lenguajes de programaci�n funcional y Lisp. Con la palabra clave lambda es posible crear peque�as funciones an�nimas. �sta es una funci�n que devuelve la suma de sus dos argumentos: "lambda a, b: a+b". Las formas lambda se pueden utilizar siempre que se necesite un objeto funci�n. Est�n sint�cticamente restringidas a una expresi�n simple. Sem�nticamente son un caramelo sint�ctico para una definici�n de funci�n normal. Al igual que las definiciones de funciones anidadas, las formas lambda no pueden hacer referencia a las variables del �mbito que las contiene, aunque esto se puede subsanar mediante el uso juicioso de los valores de argumento por omisi�n, por ejemplo:
def montar_incrementador(n): return lambda x, incr=n: x+incr
Hay convenciones crecientes sobre el contenido y formato de las cadenas de documentaci�n.
La primera l�nea debe ser siempre un corto y conciso resumen de lo que debe hacer el objeto. En aras de la brevedad, no debes hacer constar el nombre y tipo del objeto, pues �stos est�n disponibles mediante otros modos (excepto si el nombre es un verbo que describe el funcionamiento de la funci�n). Esta l�nea debe empezar por may�scula y terminar en punto.
Si hay m�s l�neas en la cadena de documentaci�n, la segunda l�nea debe ir en blanco, separando visualmente el resumen del resto de la descripci�n. Las siguientes l�neas deben ser p�rrafos que describan las convenciones de llamada de los objetos, sus efectos secundarios, etc.
El analizador de Python no elimina el sangrado de los literales multil�nea, as� que las herramientas que procesen documentaci�n tienen que eliminar el sangrado si se desea. Esto se realiza del siguiente modo. La primera l�nea que no est� en blanco tras la primera l�nea de la documentaci�n determina el grado de sangrado de la cadena de documentaci�n entera (no se puede utilizar la primera l�nea, porque suele estar pegada a las comillas de apertura y su sangrado no es evidente dentro del literal). Se elimina el espacio en blanco ``equivalente'' a este sangrado del principio de todas las l�neas de la cadena. No deber�a haber l�neas menos sangradas, pero si las hay se debe eliminar su espacio en blanco inicial. La equivalencia del espacio en blanco se debe realizar tras la expansi�n de los tabuladores (a 8 espacios, normalmente).
He aqu� un ejemplo de una cadena de documentaci�n multil�nea:
>>> def mi_funcion(): ... """No hacer nada, pero comentarlo muy bien. ... ... Que no, que no hace nada. ... """ ... pass ... >>> print mi_funcion.__doc__ No hacer nada, pero comentarlo muy bien. Que no, que no hace nada.