Guía de aprendizaje de Python

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.

.�Construcciones if

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.

.�Sentencias for

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�]

.�La funci�n range()

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

.�Construcciones con break, continue y else en bucles

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

.�Construcciones con pass

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
...

.�Definici�n de funciones

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 objeto 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]

Este ejemplo, como es habitual, demuestra algunas caracter�sticas nuevas de Python:

  • La sentencia return devuelve la ejecuci�n al que llam� a la funci�n, devolviendo un valor. Se utiliza return sin argumento para salir de una funci�n en medio de la funci�n (si se acaba el c�digo de la funci�n, tambi�n nos �caemos� de la funci�n), en cuyo caso se devuelve None.
  • La sentencia 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.

.�M�s sobre la definici�n de funciones

Tambi�n es posible definir funciones con un n�mero variable de argumentos. Existen tres formas, que se pueden combinar.

Valores por omisi�n en los argumentos

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

Argumentos por clave

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, "!"
<para>puede invocarse de estas maneras:</para>
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

Listas de argumentos arbitrarias

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)

Formas lambda

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

Cadenas de documentaci�n

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.

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP
ARTÍCULO ANTERIOR