3.1. Un poco de Sintaxis

La sintaxis de Python es realmente sencilla. No hay palabras reservadas para iniciar o finalizar bloques ni programas, no es necesario declarar variables...

Podemos usar Python como calculadora:


>>> 4 + 8
12
>>> 3 * 9
27
>>> 384621049783050943275943859347698456 * 43985794334755147354874532874587345
16917862392574899678353103753153694647500659173694689166079616493639320L
>>> 
>>> 3 / 2
1
>>> 3.0 / 2
1.5
>>> 10 % 3
1

No existen desbordamientos (los enteros pueden ser arbitrariamente grandes) y la división entera redondea hacia abajo. Veamos ahora los bucles y sentencias de decisión:


>>> while a < 10 :
...     print a
...     a = a + 3
...
1
4
7

El bucle while funciona de modo similar al de otros lenguajes.


>>> if a != 10 :
...     pass
... else :
...     print a
...
10

La sentencia if tiene el comportamiento esperado.


>>> for x in range(5):
...     print x
...
0
1
2
3
4

>>> secuencia = [ 1,'pepe',4.2,['juan','paco', 7],2]
>>> for x in secuencia:
...     print x
...
1
pepe
4.2
['juan', 'paco', 7]
2

El for es un poco diferente a los for habituales. for en Python exige una secuencia tras la palabra in. Por secuencia entenderemos listas o tuplas. Ya hablaremos de ellas. La instrucción range sirve para generar una secuencia del 0 al valor que fijemos. También es posible pasarle un intervalo para generar una secuencia entre los valores que pasamos. la variable de for (en este caso x) tomará cada valor de la secuencia. Esto se aprecia mejor en el segundo ejemplo. Veamos ahora este ejemplo:


>>> a = 3
>>> while a != 0 :
...     print a
...     a = a - 1
... else :
...     print 'Ya terminamos el bucle'
...
3
2
1
Ya terminamos el bucle
>>> a = 3
>>> while a != 0:
...     print a
...     a = a - 1
...     if a == 0:
...             break
... else:
...     print 'Ya terminamos el bucle'
...
3
2
1

Es posible incluir una clausula else al final de un bucle while. Esta se ejecutará al finalizar el while a no ser que hayamos abandonado dicho bucle con una sentencia break.

Si nos fijamos un poco en el código visto hasta ahora, observamos que mantiene un sangrado coherente en cada uno de los bloques. Por ejemplo en Pascal tenemos:


while (condición) do
Begin
	sentencia 1;
	...
	sentencia n;
End;

Observamos que existen delimitadores de bloque que entiende la máquina (Begin y End, { y } en C) y delimitadores de bloque que entendemos los humanos (el sangrado). Estos últimos no son obligatorios, sólo sirven para hacer el código más legible. En cierto modo Begin/End y el sangrado representan el concepto de bloque, son redundantes. Python no utiliza palabras reservadas para delimitar bloques, utiliza el sangrado. Es por ello que el código Python presenta siempre una estructura muy ordenada (de otro modo el intérprete daría error). Veamos la confirmación de que los delimitadores no son necesarios:


>>> for x in range(10):
...     print 'Número de la secuencia:', x
...     if x % 2 == 0 :
...             print '%d es par' % x
...             if not(x % 4) :
...                     print '%s es múltiplo de 4' % str(x)
...
Número de la secuencia: 0
0 es par
0 es múltiplo de 4
Número de la secuencia: 1
Número de la secuencia: 2
2 es par
Número de la secuencia: 3
Número de la secuencia: 4
4 es par
4 es múltiplo de 4
Número de la secuencia: 5
Número de la secuencia: 6
6 es par
Número de la secuencia: 7
Número de la secuencia: 8
8 es par
8 es múltiplo de 4
Número de la secuencia: 9

Como vemos, es el propio Python el que nos obliga a adoptar buenas técnicas de identación. El resultado es un código más claro. Este ejemplo merece algún comentario adicional:

Hemos comentado con anterioridad de los tipos avanzados de datos que implemente Python directamente. Principalmente son tres: listas, tuplas y diccionarios. Las listas son estructuras de datos que almacenan secuencias de cualquier tipo de datos. Son ampliamente utilizadas en Python. Son objetos mutables, esto es, podemos modificar cada uno de sus componentes:


>>> lista = ['pepe',1,6.5,[1,2],38264274572663375]
>>> lista[0]
'pepe'
>>> lista[3]
[1, 2]
>>> lista[:3]
['pepe', 1, 6.5]
>>> lista[1:3]
[1, 6.5]
>>> lista[1:]
[1, 6.5, [1, 2], 38264274572663375L]
>>> lista.append('nuevo_elemento')
>>> lista
['pepe', 1, 6.5, [1, 2], 38264274572663375L, 'nuevo_elemento']
>>> lista[2] = '3265732'
>>> lista
['pepe', 1, '3265732', [1, 2], 38264274572663375L, 'nuevo_elemento']

Las tuplas son similares a las listas, salvo que en este caso no son mutables, no podemos modificar sus elementos :


>>> tupla = (1,4324,233.45,'hola')
>>> tupla[1] = 'noooo'
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: object doesn't support item assignment

Los diccionarios o memorias asociativas son pares clave-valor donde clave puede ser cualquier objeto no mutable. Las claves han de ser únicas dentro de un diccionario. El mejor modo de comprender su funcionamiento es viendo un ejemplo:


>>> dic = { 233 : 'hola, que tal' , 'pepe' : 'gracias por todo' , (1,2) : 'pues
si'}
>>> dic
{233: 'hola, que tal', (1, 2): 'pues si', 'pepe': 'gracias por todo'}
>>> dic.keys()
[233, (1, 2), 'pepe']
>>> dic.has_key(233)
1

Para finalizar echaremos un vistazo a la definición de funciones:


>>> def f(x):
...     print x
...
>>> f('pepe')
pepe
>>> f(9)
9
>>> f([1,3,'paco',45.345])
[1, 3, 'paco', 45.344999999999999]

Una función se define con la palabra reservada def seguida del identificador de la función, y entre paréntesis los parámetros sin indicar su tipo. Si no hay parámetros se ponen los paréntesis vacíos (). Como se observa, se puede llamar a una función pasando parámetros de cualquier tipo. Incluso podemos hacer cosas como:


>>> f(f('pepe'))
pepe
None

Dado que no hemos especificado valor de retorno para f, la segunda llamada se hace con un argumento vacío (None).

Como ya hemos comentado, todo en Python son objetos, incluso las funciones. Sus atributos y métodos son:


>>> dir(f)
['__call__', '__class__', '__delattr__', '__dict__', '__doc__', '__get__',
'__getattribute__', '__hash__', '__init__', '__name__', '__new__', '__reduce__',


'__repr__', '__setattr__', '__str__', 'func_closure', 'func_code',
'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name']

Un atributo especialmente interesante es __doc__. En este atributo se almacenan las llamadas cadenas de documentación. Estas cadenas se colocan en la siguiente línea a la definición de la función. Sirven para aclarar qué hace la función y son ampliamente utilizadas por los IDEs (entornos integrados de desarrollo) para presentar ayuda contextual. Veamos un ejemplo de __doc__:


 >>> def g():
...     "Esto no hace nada"
...     return 7
...
>>> g()
7
>>> g.__doc__
'Esto no hace nada'

Al igual que para el resto de objetos, podemos crear un alias a nuestra función:


>>> def f():
...     print 'Hola'
...
>>> f()
Hola
>>> mi_alias = f
>>> mi_alias()
Hola

No entraremos en más detalles, pero las funciones en Python admiten argumentos por defecto, por clave e incluso admiten números indeterminados de argumentos. Tampoco hablaremos aquí de las formas lambda ni de las herramientas de programación funcional. Se invita al lector que las consulte en la guía de aprendizaje del lenguaje.