python para todos

Upload: thorset

Post on 17-Oct-2015

55 views

Category:

Documents


0 download

TRANSCRIPT

  • 5/27/2018 Python Para Todos

    1/108

    PythonPARA TODOS

    Ral Gonzlez Duque

  • 5/27/2018 Python Para Todos

    2/108

    PythonPARA TODOS

    Ral Gonzlez Duque

  • 5/27/2018 Python Para Todos

    3/108

    Python para todos

    por Ral Gonzlez Duque

    Este libro se distribuye bajo una licencia Creative Commons Reconocimien-to 2.5 Espaa. Usted es libre de:

    copiar, distribuir y comunicar pblicamente la obra

    hacer obras derivadas

    Bajo las condiciones siguientes:

    Reconocimiento. Debe reconocer y dar crdito al autor original(Ral Gonzlez Duque)

    La imgen de portada es una fotografa de una pitn verde de la especieMorelia viridis cuyo autor es Ian Chien. La fotografa est licenciada bajoCreative Commons Attribution ShareAlike 2.0

  • 5/27/2018 Python Para Todos

    4/108

    CONTENIDO

    Introduccin 6Qu es Python? 6Por qu Python? 7Instalacin de Python 8Herramientas bsicas 9

    Mi primer programa en Python 11ipos bsicos 14

    Nmeros 15Cadenas 20Booleanos 20

    Colecciones 22Listas 22

    uplas 24Diccionarios 25

    Control de flujo 27Sentencias condicionales 27Bucles 30

    Funciones 34Orientacin a Objetos 40

    Clases y objetos 40Herencia 43

    Herencia mltiple 44Polimorfismo 45Encapsulacin 46Clases de nuevo-estilo 48Mtodos especiales 48

    Revisitando Objetos 51Diccionarios 51Cadenas 52Listas 52

  • 5/27/2018 Python Para Todos

    5/108

    Programacin funcional 54Funciones de orden superior 54Iteraciones de orden superior sobre listas 56

    Funciones lambda 57Comprensin de listas 58Generadores 59Decoradores 60

    Excepciones 62Mdulos y Paquetes 69

    Mdulos 69Paquetes 72

    Entrada/Salida Y Ficheros 73

    Entrada estndar 73Parmetros de lnea de comando 74Salida estndar 74Archivos 78

    Expresiones Regulares 81Patrones 81Usando el mdulo re 85

    Sockets 88Interactuar con webs 92

    Treads 98Qu son los procesos y los threads? 98El GIL 99Treads en Python 100Sincronizacin 102Datos globales independientes 107Compartir informacin 107

  • 5/27/2018 Python Para Todos

    6/108

    6

    INTRODUCCIN

    Qu es Python?Python es un lenguaje de programacin creado por Guido van Rossuma principios de los aos 90 cuyo nombre est inspirado en el grupo decmicos ingleses Monty Python. Es un lenguaje similar a Perl, perocon una sintaxis muy limpia y que favorece un cdigo legible.

    Se trata de un lenguaje interpretado o de script, con tipado dinmico,fuertemente tipado, multiplataforma y orientado a objetos.

    Lenguaje interpretado o de scriptUn lenguaje interpretado o de script es aquel que se ejecuta utilizando

    un programa intermedio llamado intrprete, en lugar de compilar elcdigo a lenguaje mquina que pueda comprender y ejecutar directa-mente una computadora (lenguajes compilados).

    La ventaja de los lenguajes compilados es que su ejecucin es msrpida. Sin embargo los lenguajes interpretados son ms flexibles y msportables.

    Python tiene, no obstante, muchas de las caractersticas de los lengua-

    jes compilados, por lo que se podra decir que es semi interpretado. EnPython, como en Java y muchos otros lenguajes, el cdigo fuente setraduce a un pseudo cdigo mquina intermedio llamado bytecode laprimera vez que se ejecuta, generando archivos .pyc o .pyo (bytecodeoptimizado), que son los que se ejecutarn en sucesivas ocasiones.

    Tipado dinmicoLa caracterstica de tipado dinmico se refiere a que no es necesariodeclarar el tipo de dato que va a contener una determinada variable,

  • 5/27/2018 Python Para Todos

    7/108

    Introduccin

    7

    sino que su tipo se determinar en tiempo de ejecucin segn el tipodel valor al que se asigne, y el tipo de esta variable puede cambiar si se

    le asigna un valor de otro tipo.

    Fuertemente tipadoNo se permite tratar a una variable como si fuera de un tipo distintoal que tiene, es necesario convertir de forma explcita dicha variableal nuevo tipo previamente. Por ejemplo, si tenemos una variable quecontiene un texto (variable de tipo cadena o string) no podremos tra-tarla como un nmero (sumar la cadena 9y el nmero 8). En otroslenguajes el tipo de la variable cambiara para adaptarse al comporta-

    miento esperado, aunque esto es ms propenso a errores.

    MultiplataformaEl intrprete de Python est disponible en multitud de plataformas(UNIX, Solaris, Linux, DOS, Windows, OS/2, Mac OS, etc.) por loque si no utilizamos libreras especficas de cada plataforma nuestroprograma podr correr en todos estos sistemas sin grandes cambios.

    Orientado a objetosLa orientacin a objetos es un paradigma de programacin en el quelos conceptos del mundo real relevantes para nuestro problema se tras-ladan a clases y objetos en nuestro programa. La ejecucin del progra-ma consiste en una serie de interacciones entre los objetos.

    Python tambin permite la programacin imperativa, programacinfuncional y programacin orientada a aspectos.

    Por qu Python?Python es un lenguaje que todo el mundo debera conocer. Su sintaxissimple, clara y sencilla; el tipado dinmico, el gestor de memoria, lagran cantidad de libreras disponibles y la potencia del lenguaje, entreotros, hacen que desarrollar una aplicacin en Python sea sencillo, muyrpido y, lo que es ms importante, divertido.

    La sintaxis de Python es tan sencilla y cercana al lenguaje natural que

  • 5/27/2018 Python Para Todos

    8/108

    Python para todos

    8

    los programas elaborados en Python parecen pseudocdigo. Por estemotivo se trata adems de uno de los mejores lenguajes para comenzar

    a programar.

    Python no es adecuado sin embargo para la programacin de bajonivel o para aplicaciones en las que el rendimiento sea crtico.

    Algunos casos de xito en el uso de Python son Google, Yahoo, laNASA, Industrias Ligh & Magic, y todas las distribuciones Linux, enlas que Python cada vez representa un tanto por ciento mayor de losprogramas disponibles.

    Instalacin de PythonExisten varias implementaciones distintas de Python: CPython,Jython, IronPython, PyPy, etc.

    CPython es la ms utilizada, la ms rpida y la ms madura. Cuando lagente habla de Python normalmente se refiere a esta implementacin.En este caso tanto el intrprete como los mdulos estn escritos en C.

    Jython es la implementacin en Java de Python, mientras queIronPython es su contrapartida en C# (.NE). Su inters estriva enque utilizando estas implementaciones se pueden utilizar todas laslibreras disponibles para los programadores de Java y .NE.

    PyPy, por ltimo, como habris adivinado por el nombre, se trata deuna implementacin en Python de Python.

    CPython est instalado por defecto en la mayor parte de las distribu-ciones Linux y en las ltimas versiones de Mac OS. Para comprobar siest instalado abre una terminal y escribe python. Si est instalado seiniciar la consola interactiva de Python y obtendremos parecido a losiguiente:

    Python 2.5.1 (r251:54863, May 2 2007, 16:56:35)[GCC 4.1.2 (Ubuntu 4.1.2-0ubuntu4)] on linux2Type help, copyright, credits or license for moreinformation.>>>

  • 5/27/2018 Python Para Todos

    9/108

    Introduccin

    9

    La primera lnea nos indica la versin de Python que tenemos ins-

    talada. Al final podemos ver el prompt (>>>) que nos indica que elintrprete est esperando cdigo del usuario. Podemos salir escribiendoexit(), o pulsando Control + D.

    Si no te muestra algo parecido no te preocupes, instalar Python es muysencillo. Puedes descargar la versin correspondiente a tu sistema ope-rativo desde la web de Python, en http://www.python.org/download/.Existen instaladores para Windows y Mac OS. Si utilizas Linux esmuy probable que puedas instalarlo usando la herramienta de gestin

    de paquetes de tu distribucin, aunque tambin podemos descargar laaplicacin compilada desde la web de Python.

    Herramientas bsicasExisten dos formas de ejecutar cdigo Python. Podemos escribir lneasde cdigo en el intrprete y obtener una respuesta del intrprete paracada lnea (sesin interactiva) o bien podemos escribir el cdigo de unprograma en un archivo de texto y ejecutarlo.

    A la hora de realizar una sesin interactiva os aconsejo instalar y uti-lizar iPython, en lugar de la consola interactiva de Python. Se puedeencontrar en http://ipython.scipy.org/. iPython cuenta con caractersticasaadidas muy interesantes, como el autocompletado o el operador ?.

    La funcin de autocompletado se lanza pulsando el tabulador. Siescribimos fiy pulsamos ab nos mostrar una lista de los objetosque comienzan con fi (file, filtery finally). Si escribimos file. y

    pulsamos ab nos mostrar una lista de los mtodos y propiedades delobjeto file.

    El operador ?nos muestra informacin sobre los objetos. Se utilizaaadiendo el smbolo de interrogacin al final del nombre del objetodel cual queremos ms informacin. Por ejemplo:

    In [3]: str?Type: typeBase Class:String Form:

  • 5/27/2018 Python Para Todos

    10/108

    Python para todos

    10

    Namespace: Python builtinDocstring:str(object) -> string

    Return a nice string representation of the object.If the argument is a string, the return value is the sameobject.

    En el campo de IDEs y editores de cdigo gratuitos PyDEV (http://pydev.sourceforge.net/) se alza como cabeza de serie. PyDEV es un plu-gin para Eclipse que permite utilizar este IDE multiplataforma paraprogramar en Python. Cuenta con autocompletado de cdigo (coninformacin sobre cada elemento), resaltado de sintaxis, un depurador

    grfico, resaltado de errores, explorador de clases, formateo del cdigo,refactorizacin, etc. Sin duda es la opcin ms completa, sobre todo siinstalamos las extensiones comerciales, aunque necesita de una canti-dad importante de memoria y no es del todo estable.

    Otras opciones gratuitas a considerar son SPE o Stanis Python Editor(http://sourceforge.net/projects/spe/), Eric (http://die-offenbachs.de/eric/),BOA Constructor (http://boa-constructor.sourceforge.net/) o inclusoemacs o vim.

    Si no te importa desembolsar algo de dinero, Komodo (http://www.activestate.com/komodo_ide/) y Wing IDE (http://www.wingware.com/)son tambin muy buenas opciones, con montones de caractersticasinteresantes, como PyDEV, pero mucho ms estables y robustos. Ade-ms, si desarrollas software libre no comercial puedes contactar conWing Ware y obtener, con un poco de suerte, una licencia gratuita paraWing IDE Professional :)

  • 5/27/2018 Python Para Todos

    11/108

    11

    MI PRIMER

    PROGRAMA ENPYTHON

    Como comentbamos en el captulo anterior existen dos formas deejecutar cdigo Python, bien en una sesin interactiva (lnea a lnea)con el intrprete, o bien de la forma habitual, escribiendo el cdigo enun archivo de cdigo fuente y ejecutndolo.

    El primer programa que vamos a escribir en Python es el clsico Hola

    Mundo, y en este lenguaje es tan simple como:

    print Hola Mundo

    Vamos a probarlo primero en el intrprete. Ejecuta python o ipythonsegn tus preferencias, escribe la lnea anterior y pulsa Enter. El intr-prete responder mostrando en la consola el texto Hola Mundo.

    Vamos ahora a crear un archivo de texto con el cdigo anterior, deforma que pudiramos distribuir nuestro pequeo gran programa entrenuestros amigos. Abre tu editor de texto preferido o bien el IDE quehayas elegido y copia la lnea anterior. Gurdalo como hola.py, porejemplo.

    Ejecutar este programa es tan sencillo como indicarle el nombre delarchivo a ejecutar al intrprete de Python

    python hola.py

  • 5/27/2018 Python Para Todos

    12/108

    Python para todos

    12

    pero vamos a ver cmo simplificarlo an ms.

    Si utilizas Windows los archivos .py ya estarn asociados al intrpretede Python, por lo que basta hacer doble clic sobre el archivo para eje-cutar el programa. Sin embargo como este programa no hace ms queimprimir un texto en la consola, la ejecucin es demasiado rpida parapoder verlo si quiera. Para remediarlo, vamos a aadir una nueva lneaque espere la entrada de datos por parte del usuario.

    print Hola Mundoraw_input()

    De esta forma se mostrar una consola con el texto Hola Mundohastaque pulsemos Enter.

    Si utilizas Linux (u otro Unix) para conseguir este comportamiento, esdecir, para que el sistema operativo abra el archivo .py con el intrpreteadecuado, es necesario aadir una nueva lnea al principio del archivo:

    #!/usr/bin/pythonprint Hola Mundoraw_input()

    A esta lnea se le conoce en el mundo Unix como shebang, hashbango sharpbang. El par de caracteres #!indica al sistema operativo quedicho script se debe ejecutar utilizando el intrprete especificado acontinuacin. De esto se desprende, evidentemente, que si esta no es laruta en la que est instalado nuestro intrprete de Python, es necesariocambiarla.

    Otra opcin es utilizar el programa env (de environment, entorno)

    para preguntar al sistema por la ruta al intrprete de Python, de formaque nuestros usuarios no tengan ningn problema si se diera el caso deque el programa no estuviera instalado en dicha ruta:

    #!/usr/bin/env pythonprint Hola Mundoraw_input()

    Por supuesto adems de aadir el shebang, tendremos que dar permi-sos de ejecucin al programa.

  • 5/27/2018 Python Para Todos

    13/108

    Mi primer programa en Python

    13

    chmod +x hola.py

    Y listo, si hacemos doble clic el programa se ejecutar, mostrando unaconsola con el texto Hola Mundo, como en el caso de Windows.

    ambin podramos correr el programa desde la consola como si trata-ra de un ejecutable cualquiera:

    ./hola.py

  • 5/27/2018 Python Para Todos

    14/108

    14

    TIPOS BSICOS

    En Python los tipos bsicos se dividen en:

    Nmeros, como pueden ser 3(entero), 15.57(de coma flotante) o7 + 5j(complejos)Cadenas de texto, como Hola MundoValores booleanos: True(cierto) y False(falso).

    Vamos a crear un par de variables a modo de ejemplo. Una de tipocadena y una de tipo entero:

    # esto es una cadenac = Hola Mundo

    # y esto es un entero

    e = 23

    # podemos comprobarlo con la funcin typetype(c)type(e)

    Como veis en Python, a diferencia de muchos otros lenguajes, no sedeclara el tipo de la variable al crearla. En Java, por ejemplo, escribira-mos:

    String c = Hola Mundo;

    int e = 23;

    Este pequeo ejemplo tambin nos ha servido para presentar loscomentarios inline en Python: cadenas de texto que comienzan con elcarcter #y que Python ignora totalmente. Hay ms tipos de comenta-rios, de los que hablaremos ms adelante.

  • 5/27/2018 Python Para Todos

    15/108

    Tipos bsicos

    15

    NmerosComo decamos, en Python se pueden representar nmeros enteros,reales y complejos.

    EnterosLos nmeros enteros son aquellos nmeros positivos o negativos queno tienen decimales (adems del cero). En Python se pueden repre-sentar mediante el tipo int(de integer, entero) o el tipo long(largo).La nica diferencia es que el tipo longpermite almacenar nmerosms grandes. Es aconsejable no utilizar el tipo longa menos que sea

    necesario, para no malgastar memoria.

    El tipo intde Python se implementa a bajo nivel mediante un tipolongde C. Y dado que Python utiliza C por debajo, como C, y a dife-rencia de Java, el rango de los valores que puede representar dependede la plataforma.

    En la mayor parte de las mquinas el longde C se almacena utilizando32 bits, es decir, mediante el uso de una variable de tipo intde Python

    podemos almacenar nmeros de -231

    a 231

    - 1, o lo que es lo mismo, de-2.147.483.648 a 2.147.483.647. En plataformas de 64 bits, el rango esde -9.223.372.036.854.775.808 hasta 9.223.372.036.854.775.807.

    El tipo longde Python permite almacenar nmeros de cualquier preci-sin, estando limitados solo por la memoria disponible en la mquina.

    Al asignar un nmero a una variable esta pasar a tener tipo int, amenos que el nmero sea tan grande como para requerir el uso del tipo

    long.# type(entero) dara intentero = 23

    ambin podemos indicar a Python que un nmero se almacene usan-do longaadiendo una L al final:

    # type(entero) dara longentero = 23L

  • 5/27/2018 Python Para Todos

    16/108

    Python para todos

    16

    El literal que se asigna a la variable tambin se puede expresar como

    un octal, anteponiendo un cero:# 027 octal = 23 en base 10entero = 027

    o bien en hexadecimal, anteponiendo un 0x:

    # 017 hexadecimal = 23 en base 10entero = 017

    RealesLos nmeros reales son los que tienen decimales. En Python se expre-san mediante el tipo float. En otros lenguajes de programacin, comoC, tenemos tambin el tipo double, similar a floatpero de mayorprecisin (double = doble precisin). Python, sin embargo, implementasu tipo floata bajo nivel mediante una variable de tipo doublede C,es decir, utilizando 64 bits, luego en Python siempre se utiliza dobleprecisin, y en concreto se sigue el estndar IEEE 754: 1 bit para elsigno, 11 para el exponente, y 52 para la mantisa. Esto significa que los

    valores que podemos representar van desde 2,2250738585072020 x10-308 hasta 1,797693134862315710308.

    La mayor parte de los lenguajes de programacin siguen el mismoesquema para la representacin interna. Pero como muchos sabrisesta tiene sus limitaciones, impuestas por el hardware. Por eso desdePython 2.4 contamos tambin con un nuevo tipo Decimal, para elcaso de que se necesite representar fracciones de forma ms precisa.Sin embargo este tipo est fuera del alcance de este tutorial, y slo es

    necesario para el mbito de la programacin cientfica y otros rela-cionados. Para aplicaciones normales podeis utilizar el tipo floatsinmiedo, como ha venido hacindose desde hace aos, aunque teniendoen cuenta que los nmeros en coma flotante no son precisos (ni en esteni en otros lenguajes de programacin).

    Para representar un nmero real en Python se escribe primero la parteentera, seguido de un punto y por ltimo la parte decimal.

    real = 0.2703

  • 5/27/2018 Python Para Todos

    17/108

    Tipos bsicos

    17

    ambin se puede utilizar notacin cientfica, y aadir una e (de expo-

    nente) para indicar un exponente en base 10. Por ejemplo:real = 0.1e-3

    sera equivalente a 0.1 x 10-3 = 0.1 x 0.001 = 0.0001

    ComplejosLos nmeros complejos son aquellos que tienen parte imaginaria. Sino conocas de su existencia, es ms que probable que nunca lo vayas a

    necesitar, por lo que puedes saltarte este apartado tranquilamente. Dehecho la mayor parte de lenguajes de programacin carecen de estetipo, aunque sea muy utilizado por ingenieros y cientficos en general.

    En el caso de que necesitis utilizar nmeros complejos, o simplemen-te tengis curiosidad, os dir que este tipo, llamado complexen Python,tambin se almacena usando coma flotante, debido a que estos nme-ros son una extensin de los nmeros reales. En concreto se almacenaen una estructura de C, compuesta por dos variables de tipo double,

    sirviendo una de ellas para almacenar la parte real y la otra para laparte imaginaria.

    Los nmeros complejos en Python se representan de la siguienteforma:

    complejo = 2.1 + 7.8j

    Operadores

    Veamos ahora qu podemos hacer con nuestros nmeros usando losoperadores por defecto. Para operaciones ms complejas podemosrecurrir al mdulo math.

    Operadores aritmticos

    Operador Descripcin Ejemplo

    + Suma r = 3 + 2 # r es 5

    - Resta r = 4 - 7 # r es -3

  • 5/27/2018 Python Para Todos

    18/108

    Python para todos

    18

    Operador Descripcin Ejemplo

    - Negacin r = -7 # r es -7

    * Multiplicacin r = 2 * 6 # r es 12

    ** Exponente r = 2 ** 6 # r es 64

    / Divisin r = 3.5 / 2 # r es 1.75

    // Divisin entera r = 3.5 // 2 # r es 1.0

    % Mdulo r = 7 % 2 # r es 1

    Puede que tengis dudas sobre cmo funciona el operador de mdulo,y cul es la diferencia entre divisin y divisin entera.

    El operador de mdulo no hace otra cosa que devolvernos el resto dela divisin entre los dos operandos. En el ejemplo, 7/2 sera 3, con 1 deresto, luego el mdulo es 1.

    La diferencia entre divisin y divisin entera no es otra que la queindica su nombre. En la divisin el resultado que se devuelve es unnmero real, mientras que en la divisin entera el resultado que sedevuelve es solo la parte entera.

    No obstante hay que tener en cuenta que si utilizamos dos operandosenteros, Python determinar que queremos que la variable resultadotambin sea un entero, por lo que el resultado de, por ejemplo, 3 / 2y3 // 2sera el mismo: 1.

    Si quisiramos obtener los decimales necesitaramos que al menos unode los operandos fuera un nmero real, bien indicando los decimales

    r = 3.0 / 2

    o bien utilizando la funcin float(no es necesario que sepais lo quesignifica el trmino funcin, ni que recordeis esta forma, lo veremos unpoco ms adelante):

    r = float(3) / 2

    Esto es as porque cuando se mezclan tipos de nmeros, Python con-

  • 5/27/2018 Python Para Todos

    19/108

    Tipos bsicos

    19

    vierte todos los operandos al tipo ms complejo de entre los tipos delos operandos.

    Operadores a nivel de bitSi no conocis estos operadores es poco probable que vayis a necesi-tarlos, por lo que podis obviar esta parte. Si an as tenis curiosidados dir que estos son operadores que actan sobre las representacionesen binario de los operandos.

    Por ejemplo, si veis una operacin como 3 & 2, lo que estais viendo esun and bit a bit entre los nmeros binarios 11 y 10 (las representacio-

    nes en binario de 3 y 2).

    El operador and(&), del ingls y, devuelve 1 si el primer bit operandoes 1yel segundo bit operando es 1. Se devuelve 0 en caso contrario.

    El resultado de aplicar and bit a bit a 11 y 10 sera entonces el nmerobinario 10, o lo que es lo mismo, 2 en decimal (el primer dgito es 1para ambas cifras, mientras que el segundo es 1 slo para una de ellas).

    El operador or(|), del ingls o, devuelve 1 si el primer operando es 1oel segundo operando es 1. Para el resto de casos se devuelve 0.

    El operador xoru or exclusivo (^) devuelve 1 si uno de los operandoses 1 y el otro no lo es.

    El operador not(~), del ingls no, sirve para negar uno a uno cadabit; es decir, si el operando es 0, cambia a 1 y si es 1, cambia a 0.

    Por ltimo los operadores de desplazamiento () sirven paradesplazar los bits n posiciones hacia la izquierda o la derecha.

    Operador Descripcin Ejemplo

    & and r = 3 & 2 # r es 2

    | or r = 3 | 2 # r es 3

    ^ xor r = 3 ^ 2 # r es 1

    ~ not r = ~3 # r es -4

  • 5/27/2018 Python Para Todos

    20/108

    Python para todos

    20

    Desplazamiento der. r = 3 >> 1 # r es 1

    CadenasLas cadenas no son ms que texto encerrado entre comillas simples(cadena) o dobles (cadena). Dentro de las comillas se puedenaadir caracteres especiales escapndolos con \, como \n, el carcter denueva lnea, o \t, el de tabulacin.

    Una cadena puede estar precedida por el carcter uo el carcter r, los

    cuales indican, respectivamente, que se trata de una cadena que utilizacodificacin Unicode y una cadena raw(del ingls, cruda). Las cade-nas raw se distinguen de las normales en que los caracteres escapadosmediante la barra invertida (\) no se sustituyen por sus contrapartidas.Esto es especialmente til, por ejemplo, para las expresiones regulares,como veremos en el captulo correspondiente.

    unicode = uraw = r\n

    ambin es posible encerrar una cadena entre triples comillas (simpleso dobles). De esta forma podremos escribir el texto en varias lneas, yal imprimir la cadena, se respetarn los saltos de lnea que introdujimossin tener que recurrir al carcter \n, as como las comillas sin tener queescaparlas.

    Las cadenas tambin admiten operadores como +, que funciona reali-zando una concatenacin de las cadenas utilizadas como operandos y*, en la que se repite la cadena tantas veces como lo indique el nmeroutilizado como segundo operando.

    a = unob = dos

    c = a + b # c es unodosc = a * 3 # c es unounouno

    Booleanos

  • 5/27/2018 Python Para Todos

    21/108

    Tipos bsicos

    21

    Como decamos al comienzo del captulo una variable de tipo boolea-no slo puede tener dos valores: True(cierto) y False(falso). Estos

    valores son especialmente importantes para las expresiones condicio-nales y los bucles, como veremos ms adelante.

    En realidad el tipo bool(el tipo de los booleanos) es una subclase deltipo int. Puede que esto no tenga mucho sentido para t si no conoceslos trminos de la orientacin a objetos, que veremos ms adelantes,aunque tampoco es nada importante.

    Estos son los distintos tipos de operadores con los que podemos traba-

    jar con valores booleanos, los llamados operadores lgicos o condicio-nales:

    Operador Descripcin Ejemplo

    and se cumple a y b? r = True and False # r esFalse

    or se cumple a o b? r = True or False # r esTrue

    not No a r = not True # r esFalse

    Los valores booleanos son adems el resultado de expresiones queutilizan operadores relacionales (comparaciones entre valores):

    Operador Descripcin Ejemplo

    == son iguales a y b? r = 5 == 3 # r esFalse

    != son distintos a y b? r = 5 != 3 # r es

    True< es a menor que b? r = 5 < 3 # r es

    False

    > es a mayor que b? r = 5 > 3 # r esTrue

    = 3 # r esTrue

  • 5/27/2018 Python Para Todos

    22/108

    22

    COLECCIONES

    En el captulo anterior vimos algunos tipos bsicos, como los nmeros,las cadenas de texto y los booleanos. En esta leccin veremos algunostipos de colecciones de datos: listas, tuplas y diccionarios.

    ListasLa lista es un tipo de coleccin ordenada. Sera equivalente a lo que enotros lenguajes se conoce por arrays, o vectores.

    Las listas pueden contener cualquier tipo de dato: nmeros, cadenas,booleanos, y tambin listas.

    Crear una lista es tan sencillo como indicar entre corchetes, y separa-dos por comas, los valores que queremos incluir en la lista:

    l = [22, True, una lista, [1, 2]]

    Podemos acceder a cada uno de los elementos de la lista escribiendo elnombre de la lista e indicando el ndice del elemento entre corchetes.en en cuenta sin embargo que el ndice del primer elemento de lalista es 0, y no 1:

    l = [11, False]mi_var = l[0] # mi_var vale 11

    Si queremos acceder a un elemento de una lista incluida dentro de otralista tendremos que utilizar dos veces este operador, primero para in-dicar a qu posicin de la lista exterior queremos acceder, y el segundopara seleccionar el elemento de la lista interior:

    l = [una lista, [1, 2]]

  • 5/27/2018 Python Para Todos

    23/108

    Colecciones

    23

    mi_var = l[1][0] # mi_var vale 1

    ambin podemos utilizar este operador para modificar un elementode la lista si lo colocamos en la parte izquierda de una asignacin:

    l = [22, True]# Ahora l valdr [99, True]l[0] = 99

    El uso de los corchetes para acceder y modificar los elementos de unalista es comn en muchos lenguajes, pero Python nos depara variassorpresas muy agradables.

    Una curiosidad sobre el operador []de Python es que podemos utili-zar tambin nmeros negativos. Si se utiliza un nmero negativo comondice, esto se traduce en que el ndice empieza a contar desde el final,hacia la izquierda; es decir, con [-1]accederamos al ltimo elementode la lista, con [-2]al penltimo, con [-3], al antepenltimo, y assucesivamente.

    Otra cosa inusual es lo que en Python se conoce como slicingo parti-

    cionado, y que consiste en ampliar este mecanismo para permitir selec-cionar porciones de la lista. Si en lugar de un nmero escribimos dosnmeros inicioy finseparados por dos puntos (inicio:fin) Pythoninterpretar que queremos una lista que vaya desde la posicin inicioa la posicin fin, sin incluir este ltimo. Si escribimos tres nmeros(inicio:fin:salto) en lugar de dos, el tercero se utiliza para determi-nar cada cuantas posiciones aadir un elemento a la lista.

    l = [99, True, una lista, [1, 2]]mi_var = l[0:2] # mi_var vale [99, True]

    mi_var = l[0:4:2] # mi_var vale [99, una lista]

    Los nmeros negativos tambin se pueden utilizar en un slicing, con elmismo comportamiento que se coment anteriormente.

    Hay que mencionar as mismo que no es necesario indicar el principioy el final del slicing, sino que, si estos se omiten, se usarn por defectolas posiciones de inicio y fin de la lista, respectivamente:

    l = [99, True, una lista]

  • 5/27/2018 Python Para Todos

    24/108

    Python para todos

    24

    mi_var = l[1:] # mi_var vale [True, una lista]mi_var = l[:2] # mi_var vale [99, True]mi_var = l[:] # mi_var vale [99, True, una lista]

    mi_var = l[::2] # mi_var vale [99, una lista]

    ambin podemos utilizar este mecanismo para modificar la lista:

    l = [99, True, una lista, [1, 2]]l[0:2] = [0, 1] # l vale [0, 1, una lista, [1, 2]]

    pudiendo incluso modificar el tamao de la lista si la lista de la partederecha de la asignacin tiene un tamao menor o mayor que el de laseleccin de la parte izquierda de la asignacin:

    l[0:2] = [False] # l vale [False, una lista, [1, 2]]

    En todo caso las listas ofrecen mecanismos ms cmodos para ser mo-dificadas a travs de las funciones de la clase correspondiente, aunqueno veremos estos mecanismos hasta ms adelante, despus de explicarlo que son las clases, los objetos y las funciones.

    Tuplasodo lo que hemos explicado sobre las listas se aplica tambin a lastuplas, a excepcin de la forma de definirla, para lo que se utilizanparntesis en lugar de corchetes.

    t = (1, 2, True, python)

    En realidad el constructor de la tupla es la coma, no el parntesis, peroel intrprete muestra los parntesis, y nosotros deberamos utilizarlos,por claridad.

    >>> t = 1, 2, 3>>> type(t)type tuple

    Adems hay que tener en cuenta que es necesario aadir una comapara tuplas de un solo elemento, para diferenciarlo de un elementoentre parntesis.

    >>> t = (1)

  • 5/27/2018 Python Para Todos

    25/108

    Colecciones

    25

    >>> type(t)type int>>> t = (1,)

    >>> type(t)type tuple

    Para referirnos a elementos de una tupla, como en una lista, se usa eloperador []:

    mi_var = t[0] # mi_var es 1mi_var = t[0:2] # mi_var es (1, 2)

    Podemos utilizar el operador []debido a que las tuplas, al igual que

    las listas, forman parte de un tipo de objetos llamados secuencias.Permitirme un pequeo inciso para indicaros que las cadenas de textotambin son secuencias, por lo que no os extraar que podamos hacercosas como estas:

    c = hola mundoc[0] # hc[5:] # mundoc[::3] # hauo

    Volviendo al tema de las tuplas, su diferencia con las listas estriba enque las tuplas no poseen estos mecanismos de modificacin a travsde funciones tan tiles de los que hablbamos al final de la anteriorseccin.

    Adems son inmutables, es decir, sus valores no se pueden modificaruna vez creada; y tienen un tamao fijo.

    A cambio de estas limitaciones las tuplas son ms ligeras que las

    listas, por lo que si el uso que le vamos a dar a una coleccin es muybsico, puedes utilizar tuplas en lugar de listas y ahorrar memoria.

    DiccionariosLos diccionarios, tambin llamados matrices asociativas, deben sunombre a que son colecciones que relacionan una clave y un valor. Porejemplo, veamos un diccionario de pelculas y directores:

    d = {Love Actually : Richard Curtis,

  • 5/27/2018 Python Para Todos

    26/108

    Python para todos

    26

    Kill Bill: Tarantino, Amlie: Jean-Pierre Jeunet}

    El primer valor se trata de la clave y el segundo del valor asociadoa la clave. Como clave podemos utilizar cualquier valor inmutable:podramos usar nmeros, cadenas, booleanos, tuplas, pero no listaso diccionarios, dado que son mutables. Esto es as porque los diccio-narios se implementan como tablas hash, y a la hora de introducir unnuevo par clave-valor en el diccionario se calcula el hash de la clavepara despus poder encontrar la entrada correspondiente rpidamente.Si se modificara el objeto clave despus de haber sido introducido en eldiccionario, evidentemente, su hash tambin cambiara y no podra ser

    encontrado.

    La diferencia principal entre los diccionarios y las listas o las tuplas esque a los valores almacenados en un diccionario se les accede no por sundice, porque de hecho no tienen orden, sino por su clave, utilizandode nuevo el operador [].

    d[Love Actually ] # devuelve Richard Curtis

    Al igual que en listas y tuplas tambin se puede utilizar este operadorpara reasignar valores.

    d[Kill Bill] = Quentin Tarantino

    Sin embargo en este caso no se puede utilizar slicing, entre otras cosasporque los diccionarios no son secuencias, si no mappings(mapeados,asociaciones).

  • 5/27/2018 Python Para Todos

    27/108

    27

    CONTROL DE FLUJO

    En esta leccin vamos a ver los condicionales y los bucles.

    Sentencias condicionalesSi un programa no fuera ms que una lista de rdenes a ejecutar deforma secuencial, una por una, no tendra mucha utilidad. Los con-dicionales nos permiten comprobar condiciones y hacer que nuestroprograma se comporte de una forma u otra, que ejecute un fragmentode cdigo u otro, dependiendo de esta condicin.

    Aqu es donde cobran su importancia el tipo booleano y los operadoreslgicos y relacionales que aprendimos en el captulo sobre los tiposbsicos de Python.

    ifLa forma ms simple de un estamento condicional es un if(del inglssi) seguido de la condicin a evaluar, dos puntos (:) y en la siguientelnea e indentado, el cdigo a ejecutar en caso de que se cumpla dichacondicin.

    fav = mundogeek.net# si (if) fav es igual a mundogeek.net

    if fav == mundogeek.net: print Tienes buen gusto! print Gracias

    Como veis es bastante sencillo.

    Eso si, aseguraros de que indentis el cdigo tal cual se ha hecho en elejemplo, es decir, aseguraros de pulsar abulacin antes de las dos r-denes print, dado que esta es la forma de Python de saber que vuestraintencin es la de que los dos printse ejecuten slo en el caso de que

  • 5/27/2018 Python Para Todos

    28/108

    Python para todos

    28

    se cumpla la condicin, y no la de que se imprima la primera cadena sise cumple la condicin y la otra siempre, cosa que se expresara as:

    if fav == mundogeek.net: print Tienes buen gusto!print Gracias

    En otros lenguajes de programacin los bloques de cdigo se determi-nan encerrndolos entre llaves, y el indentarlos no se trata ms que deuna buena prctica para que sea ms sencillo seguir el flujo del progra-ma con un solo golpe de vista. Por ejemplo, el cdigo anterior expresa-do en Java sera algo as:

    String fav = mundogeek.net;if (fav.equals(mundogeek.net){ System.out.println(Tienes buen gusto!); System.out.println(Gracias);}

    Sin embargo, como ya hemos comentado, en Python se trata de unaobligacin, y no de una eleccin. De esta forma se obliga a los progra-madores a indentar su cdigo para que sea ms sencillo de leer :)

    if elseVamos a ver ahora un condicional algo ms complicado. Qu hara-mos si quisiramos que se ejecutaran unas ciertas rdenes en el caso deque la condicin no se cumpliera? Sin duda podramos aadir otro ifque tuviera como condicin la negacin del primero:

    if fav == mundogeek.net: print Tienes buen gusto! print Gracias

    if fav != mundogeek.net: print Vaya, que lstima

    pero el condicional tiene una segunda construccin mucho ms til:

    if fav == mundogeek.net: print Tienes buen gusto! print Graciaselse: print Vaya, que lstima

  • 5/27/2018 Python Para Todos

    29/108

    Control de flujo

    29

    Vemos que la segunda condicin se puede sustituir con un else(del

    ingls: si no, en caso contrario). Si leemos el cdigo vemos que tienebastante sentido: si fav es igual a mundogeek.net, imprime esto y esto,si no, imprime esto otro.

    if elif elif elseodava queda una construccin ms que ver, que es la que hace usodel elif.

    if numero < 0: print Negativoelif numero > 0: print Positivoelse: print Cero

    elifes una contraccin de else if, por lo tanto elif numero > 0puedeleerse como si no, si numero es mayor que 0. Es decir, primero seevala la condicin del if. Si es cierta, se ejecuta su cdigo y se con-tina ejecutando el cdigo posterior al condicional; si no se cumple,se evala la condicin del elif. Si se cumple la condicin del elif

    se ejecuta su cdigo y se continua ejecutando el cdigo posterior alcondicional; si no se cumple y hay ms de un elifse contina con elsiguiente en orden de aparicin. Si no se cumple la condicin del ifnide ninguno de los elif, se ejecuta el cdigo del else.

    A if C else B

    ambin existe una construccin similar al operador ?de otros lengua-

    jes, que no es ms que una forma compacta de expresar un ifelse. Enesta construccin se evala el predicado C y se devuelve A si se cumpleo B si no se cumple:Aif Celse B. Veamos un ejemplo:

    var = par if (num % 2 == 0) else impar

    Y eso es todo. Si conocis otros lenguajes de programacin puede queesperarais que os hablara ahora del switch, pero en Python no existeesta construccin, que podra emularse con un simple diccionario, asque pasemos directamente a los bucles.

  • 5/27/2018 Python Para Todos

    30/108

    Python para todos

    30

    BuclesMientras que los condicionales nos permiten ejecutar distintos frag-mentos de cdigo dependiendo de ciertas condiciones, los bucles nospermiten ejecutar un mismo fragmento de cdigo un cierto nmero deveces, mientras se cumpla una determinada condicin.

    whileEl bucle while(mientras) ejecuta un fragmento de cdigo mientras secumpla una condicin.

    edad = 0while edad < 18: edad = edad + 1 print Felicidades, tienes + str(edad)

    La variable edadcomienza valiendo 0. Como la condicin de que edades menor que 18 es cierta (0 es menor que 18), se entra en el bucle.Se aumenta edaden 1 y se imprime el mensaje informando de queel usuario ha cumplido un ao. Recordad que el operador +para las

    cadenas funciona concatenando ambas cadenas. Es necesario utilizarla funcin str(de string, cadena) para crear una cadena a partir delnmero, dado que no podemos concatenar nmeros y cadenas, pero yacomentaremos esto y mucho ms en prximos captulos.

    Ahora se vuelve a evaluar la condicin, y 1 sigue siendo menor que 18,por lo que se vuelve a ejecutar el cdigo que aumenta la edad en unao e imprime la edad en la pantalla. El bucle continuar ejecutndosehasta que edadsea igual a 18, momento en el cual la condicin dejar

    de cumplirse y el programa continuara ejecutando las instruccionessiguientes al bucle.

    Ahora imaginemos que se nos olvidara escribir la instruccin queaumenta la edad. En ese caso nunca se llegara a la condicin de queedadfuese igual o mayor que 18, siempre sera 0, y el bucle continuaraindefinidamente escribiendo en pantalla Has cumplido 0.

    Esto es lo que se conoce como un bucle infinito.

  • 5/27/2018 Python Para Todos

    31/108

    Control de flujo

    31

    Sin embargo hay situaciones en las que un bucle infinito es til. Por

    ejemplo, veamos un pequeo programa que repite todo lo que el usua-rio diga hasta que escriba adios.

    while True: entrada = raw_input(> ) if entrada == adios: break else: print entrada

    Para obtener lo que el usuario escriba en pantalla utilizamos la funcin

    raw_input. No es necesario que sepais qu es una funcin ni cmofunciona exactamente, simplemente aceptad por ahora que en cadaiteracin del bucle la variable entradacontendr lo que el usuarioescribi hasta pulsar Enter.

    Comprobamos entonces si lo que escribi el usuario fue adios, en cuyocaso se ejecuta la orden breako si era cualquier otra cosa, en cuyo casose imprime en pantalla lo que el usuario escribi.

    La palabra clave break(romper) sale del bucle en el que estamos.

    Este bucle se podra haber escrito tambin, no obstante, de la siguienteforma:

    salir = Falsewhile not salir: entrada = raw_input() if entrada == adios: salir = True else:

    print entrada

    pero nos ha servido para ver cmo funciona break.

    Otra palabra clave que nos podemos encontrar dentro de los bucles escontinue(continuar). Como habris adivinado no hace otra cosa quepasar directamente a la siguiente iteracin del bucle.

    edad = 0while edad < 18:

  • 5/27/2018 Python Para Todos

    32/108

    Python para todos

    32

    edad = edad + 1 if edad % 2 == 0: continue

    print Felicidades, tienes + str(edad)

    Como veis esta es una pequea modificacin de nuestro programa defelicitaciones. En esta ocasin hemos aadido un ifque comprueba sila edad es par, en cuyo caso saltamos a la prxima iteracin en lugar deimprimir el mensaje. Es decir, con esta modificacin el programa sloimprimira felicitaciones cuando la edad fuera impar.

    for in

    A los que hayis tenido experiencia previa con segn que lenguajes estebucle os va a sorprender gratamente. En Python forse utiliza comouna forma genrica de iterar sobre una secuencia. Y como tal intentafacilitar su uso para este fin.

    Este es el aspecto de un bucle foren Python:

    secuencia = [uno, dos, tres]for elemento in secuencia: print elemento

    Como hemos dicho los forse utilizan en Python para recorrer secuen-cias, por lo que vamos a utilizar un tipo secuencia, como es la lista, paranuestro ejemplo.

    Leamos la cabecera del bucle como si de lenguaje natural se tratara:para cada elemento en secuencia. Y esto es exactamente lo que haceel bucle: para cada elemento que tengamos en la secuencia, ejecutaestas lneas de cdigo.

    Lo que hace la cabecera del bucle es obtener el siguiente elemento dela secuencia secuenciay almacenarlo en una variable de nombre ele-mento. Por esta razn en la primera iteracin del bucle elementovaldruno, en la segunda dos, y en la tercera tres.

    Fcil y sencillo.

    En C o C++, por ejemplo, lo que habramos hecho sera iterar sobre las

  • 5/27/2018 Python Para Todos

    33/108

    Control de flujo

    33

    posiciones, y no sobre los elementos:

    int mi_array[] = {1, 2, 3, 4, 5};

    int i;for(i = 0; i < 5; i++) { printf(%d\n, mi_array[i]);}

    Es decir, tendramos un bucle forque fuera aumentando una variableien cada iteracin, desde 0 al tamao de la secuencia, y utilizaramosesta variable a modo de ndice para obtener cada elemento e imprimir-lo.

    Como veis el enfoque de Python es ms natural e intuitivo.

    Pero, qu ocurre si quisiramos utilizar el forcomo si estuviramos enC o en Java, por ejemplo, para imprimir los nmeros de 30 a 50? No ospreocupis, porque no necesitarais crear una lista y aadir uno a unolos nmeros del 30 al 50. Python proporciona una funcin llamadarange(rango) que permite generar una lista que vaya desde el primernmero que le indiquemos al segundo. Lo veremos despus de ver alfin a qu se refiere ese trmino tan recurrente: las funciones.

  • 5/27/2018 Python Para Todos

    34/108

    34

    FUNCIONES

    Una funcin es un fragmento de cdigo con un nombre asociado querealiza una serie de tareas y devuelve un valor. A los fragmentos decdigo que tienen un nombre asociado y no devuelven valores se lessuele llamar procedimientos. En Python no existen los procedimien-tos, ya que cuando el programador no especifica un valor de retorno lafuncin devuelve el valor None(nada), equivalente al nullde Java.

    Adems de ayudarnos a programar y depurar dividiendo el programaen partes las funciones tambin permiten reutilizar cdigo.

    En Python las funciones se declaran de la siguiente forma:

    def mi_funcion(param1, param2):

    print param1 print param2

    Es decir, la palabra clave defseguida del nombre de la funcin y entreparntesis los argumentos separados por comas. A continuacin, enotra lnea, indentado y despus de los dos puntos tendramos las lneasde cdigo que conforman el cdigo a ejecutar por la funcin.

    ambin podemos encontrarnos con una cadena de texto comoprimera lnea del cuerpo de la funcin. Estas cadenas se conocen conel nombre de docstring(cadena de documentacin) y sirven, como sunombre indica, a modo de documentacin de la funcin.

    def mi_funcion(param1, param2): Esta funcion imprime los dos valores pasados como parametros print param1 print param2

    Esto es lo que imprime el opeardor ?de iPython o la funcin help

  • 5/27/2018 Python Para Todos

    35/108

    Funciones

    35

    del lenguaje para proporcionar una ayuda sobre el uso y utilidad delas funciones. odos los objetos pueden tener docstrings, no solo las

    funciones, como veremos ms adelante.

    Volviendo a la declaracin de funciones, es importante aclarar queal declarar la funcin lo nico que hacemos es asociar un nombre alfragmento de cdigo que conforma la funcin, de forma que podamosejecutar dicho cdigo ms tarde referencindolo por su nombre. Esdecir, a la hora de escribir estas lneas no se ejecuta la funcin. Parallamar a la funcin (ejecutar su cdigo) se escribira:

    mi_funcion(hola, 2)

    Es decir, el nombre de la funcin a la que queremos llamar seguido delos valores que queramos pasar como parmetros entre parntesis. Laasociacin de los parmetros y los valores pasados a la funcin se hacenormalmente de izquierda a derecha: como a param1le hemos dado unvalor holay param2vale 2, mi_funcionimprimira hola en una lnea,y a continuacin 2.

    Sin embargo tambin es posible modificar el orden de los parmetros

    si indicamos el nombre del parmetro al que asociar el valor a la horade llamar a la funcin:

    mi_funcion(param2 = 2, param1 = hola)

    El nmero de valores que se pasan como parmetro al llamar a la fun-cin tiene que coincidir con el nmero de parmetros que la funcinacepta segn la declaracin de la funcin. En caso contrario Python sequejar:

    >>> mi_funcion(hola)Traceback (most recent call last):File , line 1, in TypeError: mi_funcion() takes exactly 2 arguments (1 given)

    ambin es posible, no obstante, definir funciones con un nmero va-riable de argumentos, o bien asignar valores por defecto a los parme-tros para el caso de que no se indique ningn valor para ese parmetroal llamar a la funcin.

  • 5/27/2018 Python Para Todos

    36/108

    Python para todos

    36

    Los valores por defecto para los parmetros se definen situando un

    signo igual despus del nombre del parmetro y a continuacin el valorpor defecto:

    def imprimir(texto, veces = 1): print veces * texto

    En el ejemplo anterior si no indicamos un valor para el segundoparmetro se imprimir una sola vez la cadena que le pasamos comoprimer parmetro:

    >>> imprimir(hola)hola

    si se le indica otro valor, ser este el que se utilice:

    >>> imprimir(hola, 2)holahola

    Para definir funciones con un nmero variable de argumentos coloca-mos un ltimo parmetro para la funcin cuyo nombre debe preceder-

    se de un signo *:

    def varios(param1, param2, *otros): for val in otros: print otros

    varios(1, 2)varios(1, 2, 3)varios(1, 2, 3, 4)

    Esta sintaxis funciona creando una tupla (de nombre otrosen el

    ejemplo) en la que se almacenan los valores de todos los parmetrosextra pasados como argumento. Para la primera llamada, varios(1, 2),la tupla otros estara vaca dado que no se han pasado ms parmetrosque los dos definidos por defecto, por lo tanto no se imprimira nada.En la segunda llamada otros valdra (3, ), y en la tercera (3, 4).

    ambin se puede preceder el nombre del ltimo parmetro con **, encuyo caso en lugar de una tupla se utilizara un diccionario. Las clavesde este diccionario seran los nombres de los parmetros indicados al

  • 5/27/2018 Python Para Todos

    37/108

    Funciones

    37

    llamar a la funcin y los valores del diccionario, los valores asociados aestos parmetros.

    En el siguiente ejemplo se utiliza la funcin itemsde los diccionarios,que devuelve una lista con sus elementos, para imprimir los parmetrosque contiene el diccionario.

    def varios(param1, param2, **otros): for i in otros.items(): print i

    varios(1, 2, tercero = 3)

    Los que conozcis algn otro lenguaje de programacin os estarispreguntando si en Python al pasar una variable como argumento deuna funcin estas se pasan por referencia o por valor. En el paso porreferencia lo que se pasa como argumento es una referencia o punteroa la variable, es decir, la direccin de memoria en la que se encuentra elcontenido de la variable, y no el contenido en si. En el paso por valor,por el contrario, lo que se pasa como argumento es el valor que conte-na la variable.

    La diferencia entre ambos estriba en que en el paso por valor loscambios que se hagan sobre el parmetro no se ven fuera de la fun-cin, dado que los argumentos de la funcin son variables locales a lafuncin que contienen los valores indicados por las variables que sepasaron como argumento. Es decir, en realidad lo que se le pasa a lafuncin son copias de los valores y no las variables en si.

    Si quisiramos modificar el valor de uno de los argumentos y que estoscambios se reflejaran fuera de la funcin tendramos que pasar el par-

    metro por referencia.

    En C los argumentos de las funciones se pasan por valor, aunque sepuede simular el paso por referencia usando punteros. En Java tambinse usa paso por valor, aunque para las variables que son objetos lo quese hace es pasar por valor la referencia al objeto, por lo que en realidadparece paso por referencia.

    En Python tambin se utiliza el paso por valor de referencias a objetos,

  • 5/27/2018 Python Para Todos

    38/108

    Python para todos

    38

    como en Java, aunque en el caso de Python, a diferencia de Java, todoes un objeto (para ser exactos lo que ocurre en realidad es que al objeto

    se le asigna otra etiqueta o nombre en el espacio de nombres local de lafuncin).

    Sin embargo no todos los cambios que hagamos a los parmetrosdentro de una funcin Python se reflejarn fuera de esta, ya que hayque tener en cuenta que en Python existen objetos inmutables, comolas tuplas, por lo que si intentramos modificar una tupla pasada comoparmetro lo que ocurrira en realidad es que se creara una nueva ins-tancia, por lo que los cambios no se veran fuera de la funcin.

    Veamos un pequeo programa para demostrarlo:

    def f(x, y): x = x + 3 y.append(23) print x, y

    x = 22y = [22]f(x, y)print x, y

    El resultado de la ejecucin de este programa sera

    25 [22, 23]22 [22, 23]

    Como vemos la variable xno conserva los cambios una vez salimos dela funcin porque los enteros son inmutables en Python. Sin embargola variable ysi los conserva, porque las listas son mutables.

    En resumen: los valores mutables se comportan como paso por refe-rencia, y los inmutables como paso por valor.

    Con esto terminamos todo lo relacionado con los parmetros de lasfunciones. Veamos por ltimo cmo devolver valores, para lo que seutiliza la palabra clave return:

    def sumar(x, y): return x + y

  • 5/27/2018 Python Para Todos

    39/108

    Funciones

    39

    print sumar(3, 2)

    Como vemos esta funcin tan sencilla no hace otra cosa que sumar losvalores pasados como parmetro y devolver el resultado como valor deretorno.

    ambin podramos pasar varios valores que retornar a return.

    def f(x, y): return x * 2, y * 2

    a, b = f(1, 2)

    Sin embargo esto no quiere decir que las funciones Python puedan de-volver varios valores, lo que ocurre en realidad es que Python crea unatupla al vuelo cuyos elementos son los valores a retornar, y esta nicavariable es la que se devuelve.

  • 5/27/2018 Python Para Todos

    40/108

    40

    ORIENTACIN A

    OBJETOS

    En el captulo de introduccin ya comentbamos que Python es unlenguaje multiparadigma en el se poda trabajar con programacin es-tructurada, como venamos haciendo hasta ahora, o con programacinorientada a objetos o programacin funcional.

    La Programacin Orientada a Objetos (POO u OOP segn sus siglasen ingls) es un paradigma de programacin en el que los conceptosdel mundo real relevantes para nuestro problema se modelan a travsde clases y objetos, y en el que nuestro programa consiste en una serie

    de interacciones entre estos objetos.

    Clases y objetosPara entender este paradigma primero tenemos que comprender qu esuna clase y qu es un objeto. Un objeto es una entidad que agrupa unestado y una funcionalidad relacionadas. El estado del objeto se definea travs de variables llamadas atributos, mientras que la funcionalidadse modela a travs de funciones a las que se les conoce con el nombrede mtodos del objeto.

    Un ejemplo de objeto podra ser un coche, en el que tendramos atri-butos como la marca, el nmero de puertas o el tipo de carburante ymtodos como arrancar y parar. O bien cualquier otra combinacin deatributos y mtodos segn lo que fuera relevante para nuestro progra-ma.

    Una clase, por otro lado, no es ms que una plantilla genrica a partir

  • 5/27/2018 Python Para Todos

    41/108

    Orientacin a objetos

    41

    de la cul instanciar los objetos; plantilla que es la que define qu atri-butos y mtodos tendrn los objetos de esa clase.

    Volviendo a nuestro ejemplo: en el mundo real existe un conjunto deobjetos a los que llamamos coches y que tienen un conjunto de atribu-tos comunes y un comportamiento comn, esto es a lo que llamamosclase. Sin embargo, mi coche no es igual que el coche de mi vecino, yaunque pertenecen a la misma clase de objetos, son objetos distintos.

    En Python las clases se definen mediante la palabra clave classsegui-da del nombre de la clase, dos puntos (:) y a continuacin, indentado,

    el cuerpo de la clase. Como en el caso de las funciones, si la primeralnea del cuerpo se trata de una cadena de texto, esta ser la cadena dedocumentacin de la clase o docstring.

    class Coche: Abstraccion de los objetos coche. def __init__(self, gasolina): self.gasolina = gasolina print Tenemos, gasolina, litros

    def arrancar(self): if self.gasolina > 0:

    print Arranca else: print No arranca

    def conducir(self): if self.gasolina > 0: self.gasolina -= 1 print Quedan, self.gasolina, litros else: print No se mueve

    Lo primero que llama la atencin en el ejemplo anterior es el nombretan curioso que tiene el mtodo __init__. Este nombre es una conven-cin y no un capricho. El mtodo __init__, con una doble barra baja alprincipio y final del nombre, se ejecuta justo despus de crear un nuevoobjeto a partir de la clase, proceso que se conoce con el nombre deinstanciacin. El mtodo __init__sirve, como sugiere su nombre, pararealizar cualquier proceso de inicializacin que sea necesario.

    Como vemos el primer parmetro de __init__y del resto de mtodos

  • 5/27/2018 Python Para Todos

    42/108

    Python para todos

    42

    de la clase es siempre self. Esta es una idea inspirada en Modula-3 ysirve para referirse al objeto actual. Este mecanismo es necesario para

    poder acceder a los atributos y mtodos del objeto diferenciando, porejemplo, una variable local mi_varde un atributo del objeto self.mi_var.

    Si volvemos al mtodo __init__de nuestra clase Cocheveremos cmose utiliza selfpara asignar al atributo gasolina del objeto (self.gaso-lina) el valor que el programador especific para el parmetro gasoli-na. El parmetro gasolinase destruye al final de la funcin, mientrasque el atributo gasolinase conserva (y puede ser accedido) mientras elobjeto viva.

    Para crear un objeto se escribira el nombre de la clase seguido de cual-quier parmetro que sea necesario entre parntesis. Estos parmetrosson los que se pasarn al mtodo __init__, que como decamos es elmtodo que se llama al instanciar la clase.

    mi_coche = Coche(3)

    Os preguntareis entonces cmo es posible que a la hora de crear nues-

    tro primer objeto pasemos un solo parmetro a __init__, el nmero3, cuando la definicin de la funcin indica claramente que precisa dedos parmetros (selfy gasolina). Esto es as porque Python pasa elprimer argumento (la referencia al objeto que se crea) automgicamen-te.

    Ahora que ya hemos creado nuestro objeto, podemos acceder a susatributos y mtodos mediante la sintaxis objeto.atributoy objeto.metodo():

    >>> print mi_coche.gasolina3>>> mi_coche.arrancar()Arranca>>> mi_coche.conducir()Quedan 2 litros>>> mi_coche.conducir()Quedan 1 litros>>> mi_coche.conducir()Quedan 0 litros>>> mi_coche.conducir()

  • 5/27/2018 Python Para Todos

    43/108

    Orientacin a objetos

    43

    No se mueve>>> mi_coche.arrancar()No arranca

    >>> print mi_coche.gasolina0

    Como ltimo apunte recordar que en Python, como ya se comenten repetidas ocasiones anteriormente, todo son objetos. Las cadenas,por ejemplo, tienen mtodos como upper(), que devuelve el texto enmaysculas o count(sub), que devuelve el nmero de veces que seencontr la cadena suben el texto.

    HerenciaHay tres conceptos que son bsicos para cualquier lenguaje de pro-gramacin orientado a objetos: el encapsulamiento, la herencia y elpolimorfismo.

    En un lenguaje orientado a objetos cuando hacemos que una clase(subclase) herede de otra clase (superclase) estamos haciendo que lasubclase contenga todos los atributos y mtodos que tena la supercla-se. No obstante al acto de heredar de una clase tambin se le llama amenudo extender una clase.

    Supongamos que queremos modelar los instrumentos musicales deuna banda, tendremos entonces una clase Guitarra, una clase Batera,una clase Bajo, etc. Cada una de estas clases tendr una serie de atribu-tos y mtodos, pero ocurre que, por el mero hecho de ser instrumentosmusicales, estas clases compartirn muchos de sus atributos y mtodos;un ejemplo sera el mtodo tocar().

    Es ms sencillo crear un tipo de objeto Instrumentocon las atributos ymtodos comunes e indicar al programa que Guitarra, Bateray Bajoson tipos de instrumentos, haciendo que hereden de Instrumento.

    Para indicar que una clase hereda de otra se coloca el nombre de la cla-se de la que se hereda entre parntesis despus del nombre de la clase:

    class Instrumento: def __init__(self, precio):

  • 5/27/2018 Python Para Todos

    44/108

    Python para todos

    44

    self.precio = precio

    def tocar(self):

    print Estamos tocando musica

    def romper(self): print Eso lo pagas tu print Son, self.precio, $$$

    class Bateria(Instrumento): pass

    class Guitarra(Instrumento): pass

    Como Bateriay Guitarraheredan de Instrumento, ambos tienen unmtodo tocar()y un mtodo romper(), y se inicializan pasando unparmetro precio. Pero, qu ocurrira si quisiramos especificar unnuevo parmetro tipo_cuerdaa la hora de crear un objeto Guitarra?Bastara con escribir un nuevo mtodo __init__para la clase Guitarraque se ejecutara en lugar del __init__de Instrumento. Esto es lo quese conoce como sobreescribir mtodos.

    Ahora bien, puede ocurrir en algunos casos que necesitemos sobrees-

    cribir un mtodo de la clase padre, pero que en ese mtodo queramosejecutar el mtodo de la clase padre porque nuestro nuevo mtodo nonecesite ms que ejecutar un par de nuevas instrucciones extra. En esecaso usaramos la sintaxis SuperClase.metodo(self, args)para llamaral mtodo de igual nombre de la clase padre. Por ejemplo, para llamaral mtodo __init__de Instrumentodesde Guitarrausaramos Instru-mento.__init__(self, precio)

    Observad que en este caso si es necesario especificar el parmetro self.

    Herencia mltipleEn Python, a diferencia de otros lenguajes como Java o C#, se permitela herencia mltiple, es decir, una clase puede heredar de varias clases ala vez. Por ejemplo, podramos tener una clase Cocodriloque heredarade la clase Terrestre, con mtodos como caminar()y atributos comovelocidad_caminary de la clase Acuatico, con mtodos como nadar()y atributos como velocidad_nadar. Basta con enumerar las clases de

  • 5/27/2018 Python Para Todos

    45/108

    Orientacin a objetos

    45

    las que se hereda separndolas por comas:

    class Cocodrilo(Terrestre, Acuatico):

    pass

    En el caso de que alguna de las clases padre tuvieran mtodos con elmismo nombre y nmero de parmetros las clases sobreescribiran laimplementacin de los mtodos de las clases ms a su derecha en ladefinicin.

    En el siguiente ejemplo, como Terrestrese encuentra ms a la iz-quierda, sera la definicin de desplazarde esta clase la que prevale-

    cera, y por lo tanto si llamamos al mtodo desplazarde un objeto detipo Cocodrilolo que se imprimira sera El animal anda.

    class Terrestre: def desplazar(self): print El animal anda

    class Acuatico: def desplazar(self): print El animal nada

    class Cocodrilo(Terrestre, Acuatico): pass

    c = Cocodrilo()c.desplazar()

    PolimorfismoLa palabra polimorfismo, del latnpolys morphos(varias formas), se re-fiere a la habilidad de objetos de distintas clases de responder al mismomensaje. Esto se puede conseguir a travs de la herencia: un objeto deuna clase derivada es al mismo tiempo un objeto de la clase padre, deforma que all donde se requiere un objeto de la clase padre tambin sepuede utilizar uno de la clase hija.

    Python, al ser de tipado dinmico, no impone restricciones a los tiposque se le pueden pasar a una funcin, por ejemplo, ms all de que elobjeto se comporte como se espera: si se va a llamar a un mtodo f()del objeto pasado como parmetro, por ejemplo, evidentemente elobjeto tendr que contar con ese mtodo. Por ese motivo, a diferencia

  • 5/27/2018 Python Para Todos

    46/108

    Python para todos

    46

    de lenguajes de tipado esttico como Java o C++, el polimorfismo enPython no es de gran importancia.

    En ocasiones tambin se utiliza el trmino polimorfismo para referirsea la sobrecarga de mtodos, trmino que se define como la capacidaddel lenguaje de determinar qu mtodo ejecutar de entre varios mto-dos con igual nombre segn el tipo o nmero de los parmetros que sele pasa. En Python no existe sobrecarga de mtodos (el ltimo mtodosobreescribira la implementacin de los anteriores), aunque se puedeconseguir un comportamiento similar recurriendo a funciones con va-lores por defecto para los parmetros o a la sintaxis *paramso **params

    explicada en el captulo sobre las funciones en Python, o bien usandodecoradores (mecanismo que veremos ms adelante).

    EncapsulacinLa encapsulacin se refiere a impedir el acceso a determinados m-todos y atributos de los objetos estableciendo as qu puede utilizarsedesde fuera de la clase.

    Esto se consigue en otros lenguajes de programacin como Java utili-zando modificadores de acceso que definen si cualquiera puede accedera esa funcin o variable (public) o si est restringido el acceso a lapropia clase (private).

    En Python no existen los modificadores de acceso, y lo que se suelehacer es que el acceso a una variable o funcin viene determinado porsu nombre: si el nombre comienza con dos guiones bajos (y no terminatambin con dos guiones bajos) se trata de una variable o funcin pri-vada, en caso contrario es pblica. Los mtodos cuyo nombre comien-za y termina con dos guiones bajos son mtodos especiales que Pythonllama automticamente bajo ciertas circunstancias, como veremos alfinal del captulo.

    En el siguiente ejemplo slo se imprimir la cadena correspondiente almtodo publico(), mientras que al intentar llamar al mtodo __pri-vado()Python lanzar una excepcin quejndose de que no existe(evidentemente existe, pero no lo podemos ver porque es privado).

  • 5/27/2018 Python Para Todos

    47/108

    Orientacin a objetos

    47

    class Ejemplo: def publico(self):

    print Publico

    def __privado(self): print Privado

    ej = Ejemplo()ej.publico()ej.__privado()

    Este mecanismo se basa en que los nombres que comienzan con undoble guin bajo se renombran para incluir el nombre de la clase. Esto

    implica que el mtodo o atributo no es realmente privado, y podemosacceder a l mediante una pequea trampa:

    ej._Ejemplo__privado()

    En ocasiones tambin puede suceder que queramos permitir el accesoa algn atributo de nuestro objeto, pero que este se produzca de formacontrolada. Para esto podemos escribir mtodos cuyo nico cometidosea este, mtodos que normalmente, por convencin, tienen nombrescomo getVariabley setVariable; de ah que se conozcan tambin conel nombre degettersy setters.

    class Fecha(): def __init__(self): self.__dia = 1

    def getDia(self): return self.__dia

    def setDia(self, dia): if dia > 0 and dia < 31:

    self.__dia = dia else: print Error

    mi_fecha = Fecha()mi_fecha.setDia(33)

    Esto se podra simplificar mediante propiedades, que abstraen al usua-rio del hecho de que se est utilizando mtodos entre bambalinas paraobtener y modificar los valores del atributo:

  • 5/27/2018 Python Para Todos

    48/108

    Python para todos

    48

    class Fecha(object): def __init__(self): self.__dia = 1

    def getDia(self): return self.__dia

    def setDia(self, dia): if dia > 0 and dia < 31: self.__dia = dia else: print Error

    dia = property(getDia, setDia)

    mi_fecha = Fecha()mi_fecha.dia = 33

    Clases de nuevo-estiloEn el ejemplo anterior os habr llamado la atencin el hecho de que laclase Fechaderive de object. La razn de esto es que para poder usarpropiedades la clase tiene que ser de nuevo-estilo, clases enriquecidasintroducidas en Python 2.2 que sern el estndar en Python 3.0 peroque an conviven con las clases clsicas por razones de retrocompa-

    tibilidad. Adems de las propiedades las clases de nuevo estilo aadenotras funcionalidades como descriptores o mtodos estticos.

    Para que una clase sea de nuevo estilo es necesario, por ahora, queextienda una clase de nuevo-estilo. En el caso de que no sea necesa-rio heredar el comportamiento o el estado de ninguna clase, como ennuestro ejemplo anterior, se puede heredar de object, que es un objetovacio que sirve como base para todas las clases de nuevo estilo.

    La diferencia principal entre las clases antiguas y las de nuevo estiloconsiste en que a la hora de crear una nueva clase anteriormente no sedefina realmente un nuevo tipo, sino que todos los objetos creados apartir de clases, fueran estas las clases que fueran, eran de tipo instan-ce.

    Mtodos especialesYa vimos al principio del artculo el uso del mtodo __init__. Exis-

  • 5/27/2018 Python Para Todos

    49/108

    Orientacin a objetos

    49

    ten otros mtodos con significados especiales, cuyos nombres siemprecomienzan y terminan con dos guiones bajos. A continuacin se listan

    algunos especialmente tiles.__init__(self, args)

    Mtodo llamado despus de crear el objeto para realizar tareas deinicializacin.

    __new__(cls, args)

    Mtodo exclusivo de las clases de nuevo estilo que se ejecuta antes que__init__y que se encarga de construir y devolver el objeto en s. Esequivalente a los constructores de C++ o Java. Se trata de un mtodo

    esttico, es decir, que existe con independencia de las instancias dela clase: es un mtodo de clase, no de objeto, y por lo tanto el primerparmetro no es self, sino la propia clase: cls.

    __del__(self)

    Mtodo llamado cuando el objeto va a ser borrado. ambin llamadodestructor, se utiliza para realizar tareas de limpieza.

    __str__(self)

    Mtodo llamado para crear una cadena de texto que represente a nues-tro objeto. Se utiliza cuando usamos printpara mostrar nuestro objetoo cuando usamos la funcin str(obj)para crear una cadena a partir denuestro objeto.

    __cmp__(self, otro)

    Mtodo llamado cuando se utilizan los operadores de comparacinpara comprobar si nuestro objeto es menor, mayor o igual al objetopasado como parmetro. Debe devolver un nmero negativo si nuestroobjeto es menor, cero si son iguales, y un nmero positivo si nuestro

    objeto es mayor. Si este mtodo no est definido y se intenta com-parar el objeto mediante los operadores =se lanzar unaexcepcin. Si se utilizan los operadores ==o !=para comprobar si dosobjetos son iguales, se comprueba si son el mismo objeto (si tienen elmismo id).

    __len__(self)

    Mtodo llamado para comprobar la longitud del objeto. Se utiliza, porejemplo, cuando se llama a la funcin len(obj)sobre nuestro objeto.

  • 5/27/2018 Python Para Todos

    50/108

    Python para todos

    50

    Como es de suponer, el mtodo debe devolver el nmero la longituddel objeto.

    Existen bastantes ms mtodos especiales, que permite entre otrascosas utilizar el mecanismo de slicing sobre nuestro objeto, utilizarlos operadores aritmticos o usar la sintaxis de diccionarios, pero unestudio exhaustivo de todos los mtodos queda fuera del propsito delcaptulo.

  • 5/27/2018 Python Para Todos

    51/108

    51

    REVISITANDO

    OBJETOS

    En los captulos dedicados a los tipos simples y las colecciones veamospor primera vez algunos de los objetos del lenguaje Python: nmeros,booleanos, cadenas de texto, diccionarios, listas y tuplas.

    Ahora que sabemos qu son las clases, los objetos, las funciones, y losmtodos es el momento de revisitar estos objetos para descubrir suverdadero potencial.

    Veremos a continuacin algunos mtodos tiles de estos objetos. Evi-

    dentemente, no es necesario memorizarlos, pero si, al menos, recordarque existen para cuando sean necesarios.

    DiccionariosD.has_key(k)

    Comprueba si el diccionario tiene la clave k. Es equivalente a la sin-taxis k in D.

    D.items()

    Devuelve una lista de tuplas con pares clave-valor.

    D.keys()

    Devuelve una lista de las claves del diccionario.

    D.pop(k[, d])

    Borra la clave kdel diccionario y devuelve su valor. Si no se encuentradicha clave se devuelve dsi se especific el parmetro o bien se lanza

  • 5/27/2018 Python Para Todos

    52/108

    Python para todos

    52

    una excepcin.

    D.values()Devuelve una lista de los valores del diccionario.

    CadenasS.count(sub[, start[, end]])

    Devuelve el nmero de veces que se encuentra suben la cadena. Losparmetros opcionales starty enddefinen una subcadena en la quebuscar.

    S.find(sub[, start[, end]])

    Devuelve la posicin en la que se encontr por primera vez suben lacadena o -1 si no se encontr.

    S.join(sequence)

    Devuelve una cadena resultante de concatenar las cadenas de la se-cuencia seqseparadas por la cadena sobre la que se llama el mtodo.

    S.partition(sep)

    Busca el separador sepen la cadena y devuelve una tupla con la sub-cadena hasta dicho separador, el separador en si, y la subcadena delseparador hasta el final de la cadena. Si no se encuentra el separador, latupla contendr la cadena en si y dos cadenas vacas.

    S.replace(old, new[, count])

    Devuelve una cadena en la que se han reemplazado todas las ocurren-cias de la cadena oldpor la cadena new. Si se especifica el parmetrocount, este indica el nmero mximo de ocurrencias a reemplazar.

    S.split([sep [,maxsplit]])Devuelve una lista conteniendo las subcadenas en las que se dividenuestra cadena al dividirlas por el delimitador sep. En el caso de queno se especifique sep, se usan espacios. Si se especifica maxsplit, esteindica el nmero mximo de particiones a realizar.

    ListasL.append(object)

  • 5/27/2018 Python Para Todos

    53/108

    Revisitando objetos

    53

    Aade un objeto al final de la lista.

    L.count(value)

    Devuelve el nmero de veces que se encontr valueen la lista.

    L.extend(iterable)

    Aade los elementos del iterable a la lista.

    L.index(value[, start[, stop]])

    Devuelve la posicin en la que se encontr la primera ocurrencia devalue. Si se especifican, starty stopdefinen las posiciones de inicio yfin de una sublista en la que buscar.

    L.insert(index, object)

    Inserta el objeto objecten la posicin index.

    L.pop([index])

    Devuelve el valor en la posicin indexy lo elimina de la lista. Si no seespecifica la posicin, se utiliza el ltimo elemento de la lista.

    L.remove(value)

    Eliminar la primera ocurrencia de valueen la lista.

    L.reverse()

    Invierte la lista. Esta funcin trabaja sobre la propia lista desde la quese invoca el mtodo, no sobre una copia.

    L.sort(cmp=None, key=None, reverse=False)

    Ordena la lista. Si se especifica cmp, este debe ser una funcin que tomecomo parmetro dos valores xe yde la lista y devuelva -1 si xes menorque y, 0 si son iguales y 1 si xes mayor que y.

    El parmetro reversees un booleano que indica si se debe ordenarla lista de forma inversa, lo que sera equivalente a llamar primero aL.sort()y despus a L.reverse().

    Por ltimo, si se especifica, el parmetro keydebe ser una funcin quetome un elemento de la lista y devuelva una clave a utilizar a la hora decomparar, en lugar del elemento en si.

  • 5/27/2018 Python Para Todos

    54/108

    54

    PROGRAMACIN

    FUNCIONAL

    La programacin funcional es un paradigma en el que la programa-cin se basa casi en su totalidad en funciones, entendiendo el conceptode funcin segn su definicin matemtica, y no como los simplessubprogramas de los lenguajes imperativos que hemos visto hastaahora.

    En los lenguajes funcionales puros un programa consiste exclusiva-mente en la aplicacin de distintas funciones a un valor de entradapara obtener un valor de salida.

    Python, sin ser un lenguaje puramente funcional incluye varias caracte-rsticas tomadas de los lenguajes funcionales como son las funciones deorden superior o las funciones lambda (funciones annimas).

    Funciones de orden superiorEl concepto de funciones de orden superior se refiere al uso de fun-ciones como si de un valor cualquiera se tratara, posibilitando el pasarfunciones como parmetros de otras funciones o devolver funcionescomo valor de retorno.

    Esto es posible porque, como hemos insistido ya en varias ocasiones,en Python todo son objetos. Y las funciones no son una excepcin.

    Veamos un pequeo ejemplo

    def saludar(lang): def saludar_es():

  • 5/27/2018 Python Para Todos

    55/108

    Programacin funcional

    55

    print Hola

    def saludar_en():

    print Hi

    def saludar_fr(): print Salut

    lang_func = {es: saludar_es, en: saludar_en, fr: saludar_fr} return lang_func[lang]

    f = saludar(es)f()

    Como podemos observar lo primero que hacemos en nuestro pequeoprograma es llamar a la funcin saludarcon un parmetro es. En lafuncin saludarse definen varias funciones: saludar_es, saludar_enysaludar_fry a continuacin se crea un diccionario que tiene como cla-ves cadenas de texto que identifican a cada lenguaje, y como valores lasfunciones. El valor de retorno de la funcin es una de estas funciones.La funcin a devolver viene determinada por el valor del parmetrolangque se pas como argumento de saludar.

    Como el valor de retorno de saludares una funcin, como hemosvisto, esto quiere decir que fes una variable que contiene una funcin.Podemos entonces llamar a la funcin a la que se refiere fde la formaen que llamaramos a cualquier otra funcin, aadiendo unos parnte-sis y, de forma opcional, una serie de parmetros entre los parntesis.

    Esto se podra acortar, ya que no es necesario almacenar la funcin quenos pasan como valor de retorno en una variable para poder llamarla:

    >>> saludar(en)()Hi>>> saludar(fr)()Salut

    En este caso el primer par de parntesis indica los parmetros de lafuncin saludar, y el segundo par, los de la funcin devuelta por salu-dar.

  • 5/27/2018 Python Para Todos

    56/108

    Python para todos

    56

    Iteraciones de orden superior so-

    bre listasUna de las cosas ms interesantes que podemos hacer con nuestrasfunciones de orden superior es pasarlas como argumentos de las fun-ciones map, filtery reduce. Estas funciones nos permiten sustituir losbucles tpicos de los lenguajes imperativos mediante construccionesequivalentes.

    map(function, sequence[, sequence, ...])La funcin mapaplica una funcin a cada elemento de una secuencia ydevuelve una lista con el resultado de aplicar la funcin a cada elemen-to. Si se pasan como parmetros nsecuencias, la funcin tendr queaceptar nargumentos. Si alguna de las secuencias es ms pequea quelas dems, el valor que le llega a la funcin functionpara posicionesmayores que el tamao de dicha secuencia ser None.

    A continuacin podemos ver un ejemplo en el que se utiliza mapparaelevar al cuadrado todos los elementos de una lista:

    def cuadrado(n): return n ** 2

    l = [1, 2, 3]l2 = map(cuadrado, l)

    lter(function, sequence)La funcion filterverifica que los elementos de una secuencia cum-plan una determinada condicin, devolviendo una secuencia con loselementos que cumplen esa condicin. Es decir, para cada elemento desequencese aplica la funcin function; si el resultado es Truese aadea la lista y en caso contrario se descarta.

    A continuacin podemos ver un ejemplo en el que se utiliza filterpara conservar solo los nmeros que son pares.

    def es_par(n): return (n % 2.0 == 0)

    l = [1, 2, 3]

  • 5/27/2018 Python Para Todos

    57/108

    Programacin funcional

    57

    l2 = filter(es_par, l)

    reduce(function, sequence[, initial])La funcin reduceaplica una funcin a pares de elementos de unasecuencia hasta dejarla en un solo valor.

    A continuacin podemos ver un ejemplo en el que se utiliza reducepara sumar todos los elementos de una lista.

    def sumar(x, y): return x + y

    l = [1, 2, 3]l2 = reduce(sumar, l)

    Funciones lambdaEl operador lambdasirve para crear funciones annimas en lnea. Al serfunciones annimas, es decir, sin nombre, estas no podrn ser referen-ciadas ms tarde.

    Las funciones lambda se construyen mediante el operadorlambda

    , losparmetros de la funcin separados por comas (atencin, SIN parnte-sis), dos puntos (:) y el cdigo de la funcin.

    Esta construccin podran haber sido de utilidad en los ejemplos an-teriores para reducir cdigo. El programa que utilizamos para explicarfilter, por ejemplo, podra expresarse as:

    l = [1, 2, 3]l2 = filter(lambda n: n % 2.0 == 0, l)

    Comparemoslo con la versin anterior:

    def es_par(n): return (n % 2.0 == 0)

    l = [1, 2, 3]l2 = filter(es_par, l)

    Las funciones lambda estn restringidas por la sintaxis a una sola

  • 5/27/2018 Python Para Todos

    58/108

    Python para todos

    58

    expresin.

    Comprensin de listasEn Python 3 mapy filterse vern sustituidas por las list comprehen-sionso comprensin de listas, caracterstica tomada del lenguaje deprogramacin funcional Haskell y que est presente en Python desdela versin 2.0.

    La comprensin de listas es una construccin que permite crear listasa partir de otras listas. Cada una de estas construcciones consta de una

    expresin que determina cmo modificar el elemento de la lista origi-nal, seguida de una o varias clausulas fory opcionalmente una o variasclausulas if.

    Veamos un ejemplo de cmo se podra utilizar la comprensin de listaspara elevar al cuadrado todos los elementos de una lista, como hicimosen nuestro ejemplo de map.

    l2 = [n ** 2 for n in l]

    Esta expresin se leera como para cada n en l haz n ** 2. Comovemos tenemos primero la expresin que modifica los valores de la listaoriginal (n ** 2), despus el for, el nombre que vamos a utilizar parareferirnos al elemento actual de la lista original, el in, y la lista sobre laque se itera.

    El ejemplo que utilizamos para la funcin filter(conservar solo losnmeros que son pares) se podra expresar con comprensin de listasas:

    l2 = [n for n in l if n % 2.0 == 0]

    Veamos por ltimo un ejemplo de compresin de listas con variasclausulas for:

    l = [0, 1, 2, 3]m = [a, b]n = [s * v for s in m for v in l

  • 5/27/2018 Python Para Todos

    59/108

    Programacin funcional

    59

    if v > 0]

    Esta construccin sera equivalente a una serie de for-inanidados:l = [0, 1, 2, 3]m = [a, b]n = []

    for s in m: for v in l: if v > 0: n.append(s* v)

    GeneradoresLas expresiones generadoras funcionan de forma muy similar a lacomprensin de listas. De hecho su sintaxis es exactamente igual, aexcepcin de que se utilizan parntesis en lugar de corchetes:

    l2 = (n ** 2 for n in l)

    Sin embargo las expresiones generadoras se diferencian de la compren-sin de listas en que no se devuelve una lista, sino un generador.

    >>> l2 = [n ** 2 for n in l]>>> l2[0, 1, 4, 9]>>> l2 = (n ** 2 for n in l)>>> l2

    Un generador es una clase especial de funcin que genera valores sobrelos que iterar. Para devolver el siguiente valor sobre el que iterar seutiliza la palabra clave yielden lugar de return. Veamos por ejemploun generador que devuelva nmeros de na mcon un salto s.

    def mi_generador(n, m, s): while(n >> x = mi_generador(0, 5, 1)>>> x

  • 5/27/2018 Python Para Todos

    60/108

    Python para todos

    60

    El generador se puede utilizar en cualquier lugar donde se necesite unobjeto iterable. Por ejemplo en un for-in:

    for n in mi_generador(0, 5, 1): print n

    Como no estamos creando una lista completa en memoria, sino gene-rando un solo valor cada vez que se necesita, en situaciones en las queno sea necesario tener la lista completa el uso de generadores puedesuponer una gran diferencia de memoria. En todo caso siempre es po-sible crear una lista a partir de un generador mediante la funcin list:

    lista = list(mi_generador)

    DecoradoresUn decorador no es es mas que una funcin que recibe una funcincomo parmetro y devuelve otra funcin como resultado. Por ejem-plo podramos querer aadir la funcionalidad de que se imprimiera elnombre de la funcin llamada por motivos de depuracin:

    def mi_decorador(funcion): def nueva(*args): print Llamada a la funcion, funcion.__name__ retorno = funcion(*args) return retorno return nueva

    Como vemos el cdigo de la funcin mi_decoradorno hace ms quecrear una nueva funcin y devolverla. Esta nueva funcin imprime elnombre de la funcin a la que decoramos, ejecuta el cdigo de dichafuncin, y devuelve su valor de retorno. Es decir, que si llamramos

    a la nueva funcin que nos devuelve mi_decorador, el resultado serael mismo que el de llamar directamente a la funcin que le pasamoscomo parmetro, exceptuando el que se imprimira adems el nombrede la funcin.

    Supongamos como ejemplo una funcin impque no hace otra cosa quemostrar en pantalla la cadena pasada como parmetro.

    >>> imp(hola)

  • 5/27/2018 Python Para Todos

    61/108

    Programacin funcional

    61

    hola>>> mi_decorador(imp)(hola)Llamada a la funcin imp

    hola

    La sintaxis para llamar a la funcin que nos devuelve mi_decoradornoes muy clara, aunque si lo estudiamos detenidamente veremos que notiene mayor complicacin. Primero se llama a la funcin que decoracon la funcin a decorar: mi_decorador(imp); y una vez obtenida lafuncin ya decorada se la puede llamar pasando el mismo parmetroque se pas anteriormente: mi_decorador(imp)(hola)

    Esto se podra expresar ms claramente precediendo la definicin de lafuncin que queremos decorar con el signo@seguido del nombre de lafuncin decoradora:

    @mi_decoradordef imp(s): print s

    De esta forma cada vez que se llame a impse estar llamando realmen-te a la versin decorada. Python incorpora esta sintaxis desde la versin

    2.4 en adelante.

    Si quisiramos aplicar ms de un decorador bastara aadir una nuevalnea con el nuevo decorador.

    @otro_decorador@mi_decoradordef imp(s): print s

    Es importante advertir que los decoradores se ejecutarn de abajo aarriba. Es decir, en este ejemplo primero se ejecutara mi_decoradorydespus otro_decorador.

  • 5/27/2018 Python Para Todos

    62/108

    62

    EXCEPCIONES

    Las excepciones son errores detectados por Python durante la eje-cucin del programa. Cuando el intrprete se encuentra con unasituacin excepcional, como el intentar dividir un nmero entre 0 oel intentar acceder a un archivo que no existe, este genera o lanza unaexcepcin, informando al usuario de que existe algn problema.

    Si la excepcin no se captura el flujo de ejecucin se interrumpe y semuestra la informacin asociada a la excepcin en la consola de formaque el programador pueda solucionar el problema.

    Veamos un pequeo programa que lanzara una excepcin al intentardividir 1 entre 0.

    def division(a, b): return a / b

    def calcular(): division(1, 0)

    calcular()

    Si lo ejecutamos obtendremos el siguiente mensaje de error:

    $ python ejemplo.py

    Traceback (most recent call last):File ejemplo.py, line 7, incalcular()File ejemplo.py, line 5, in calculardivision(1, 0)File ejemplo.py, line 2, in divisiona / bZeroDivisionError: integer division or modulo by zero

    Lo primero que se muestra es el trazado de pila o traceback, que con-siste en una lista con las llamadas que provocaron la excepcin. Como

  • 5/27/2018 Python Para Todos

    63/108

    Excepciones

    63

    vemos en el trazado de pila, el error estuvo causado por la llamada acalcular()de la lnea 7, que a su vez llama a division(1, 0)en la

    lnea 5 y en ltima instancia por la ejecucin de la sentencia a / bdela lnea 2 de division.

    A continuacin vemos el tipo de la excepcin, ZeroDivionError, juntoa una descripcin del error: integer division or modulo by zero (m-dulo o divisin entera entre cero).

    En Python se utiliza una construccin try-exceptpara capturar ytratar las excepciones. El bloque try(intentar) define el fragmento de

    cdigo en el que creemos que podra producirse una excepcin. El blo-que except(excepcin) permite indicar el tratamiento que se llevar acabo de producirse dicha excepcin. Muchas veces nuestro tratamientode la excepcin consistir simplemente en imprimir un mensaje msamigable para el usuario, otras veces nos interesar registrar los erroresy de vez en cuando podremos establecer una estrategia de resolucindel problema.

    En el siguiente ejemplo intentamos crear un objeto fde tipo fichero.De no existir el archivo pasado como parmetro, se lanza una excep-cin de tipo IOError, que capturamos gracias a nuestro try-except.

    try: f = file(archivo.txt)except: print El archivo no existe

    Python permite utilizar varios exceptpara un solo bloque try, deforma que podamos dar un tratamiento distinto a la excepcin de-pendiendo del tipo de excepcin de la que se trate. Esto es una buenaprctica, y es tan sencillo como indicar el nombre del tipo a continua-cin del except.

    try: num = int(3a) print no_existeexcept NameError: print La variable no existeexcept ValueError: print El valor no es un numero

  • 5/27/2018 Python Para Todos

    64/108

    Python para todos

    64

    Cuando se lanza una excepcin en el bloque try, se busca en cada unade las clausulas exceptun manejador adecuado para el tipo de error

    que se produjo. En caso de que no se encuentre, se propaga la excep-cin.

    Adems podemos hacer que un mismo exceptsirva para tratar msde una excepcin usando una tupla para listar los tipos de error quequeremos que trate el bloque:

    try: num = int(3a) print no_existeexcept (NameError, ValueError):

    print Ocurrio un error

    La construccin try-exceptpuede contar adems con una clausulaelse, que define un fragmento de cdigo a ejecutar slo si no se haproducido ninguna excepcin en el try.

    try: num = 33except: print Hubo un error!

    else: print Todo esta bien

    ambin existe una clausula finallyque se ejecuta siempre, se pro-duzca o no una excepcin. Esta clausula se suele utilizar, entre otrascosas, para tareas de limpieza.

    try: z = x / yexcept ZeroDivisionError: print Division por cero

    finally: print Limpiando

    ambin es interesante comentar que como programadores podemoscrear y lanzar nuestras propias excepciones. Basta crear una clase queherede de Exceptiono cualquiera de sus hijas y lanzarla con raise.

    class MiError(Exception): def __init__(self, valor): self.valor = valor

  • 5/27/2018 Python Para Todos

    65/108

    Excepciones

    65

    def __str__(self): return Error + str(self.valor)

    try: if resultado > 20: raise MiError(33)except MiError, e: print e

    Por ltimo, a continuacin se listan a modo de referencia las excepcio-nes disponibles por defecto, as como la clase de la que deriva cada unade ellas entre parntesis.

    BaseException: Clase de la que heredan todas las excepciones.

    Exception(BaseException) : Super clase de todas las excepciones