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:
if x % 2 == 0 : |
El operador % es el módulo. La igualdad se representa con == mientras que la asignación con =. Los dos puntos : indican inicio de un bloque. La siguiente instrucción ha de ir un paso más sangrada que la actual. Si no quisiéramos ejecutar ninguna instrucción utilizaríamos pass.
print '%d es par' % x |
Un modo de escribir las salidas como en C. Se escribe la cadena con los correspondientes identificadores de tipo, se utiliza el símbolo % y después los identificadores de las variables. No entraremos en detalles.
if not(x % 4) : |
Tanto en Python como en C, 0 es falso y lo demás es cierto. Esto se puede utilizar como en este caso. Si es múltiplo de 4, x%4 es 0 y con el not tendríamos not(falso) que es cierto.
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.