Archivo de la categoría: Python

Python es un lenguaje de programación muy utilizado actualmente en entornos relacionados con Data Science y Big Data

Su uso en librerías creadas por Google y otros gigantes tecnológicos ha hecho que en los últimos años se haya convertido en uno de los lenguajes más utilizados

Python

Python

Python es un lenguaje de programación muy utilizado actualmente en entornos relacionados con Data Science y Big Data

Su uso en librerías creadas por Google y otros gigantes tecnológicos ha hecho que en los últimos años se haya convertido en uno de los lenguajes más utilizados

Dentro de los lenguajes de programación, sus características son:

  • Interpretado

    El proceso de compilado es el de traducción del lenguaje de programación que estemos utilizando (por ejemplo C++) a código máquina que el ordenador puede ejecutar

    Además, en este proceso se crea un archivo ejecutable que puede utilizarse en otros ordenadores

    Hay lenguajes de programación que no utilizan un proceso de compilado sino un intérprete, que añade significado a las sentencias programadas

    Python es un lenguaje interpretado

  • Tipado dinámico

    El tipado de un lenguaje de programación es la forma que tiene el lenguaje de gestionar las variables y sus tipos

    Por lo general, en un lenguaje de programación se pueden crear variables de diferentes tipos (numero entero, número real, carácter, listas…)

    Existen lenguajes en los que antes de poder utilizar una variable tenemos que definirla y asignarle un tipo concreto de variable

    En un lenguaje no formal sería algo como: Quiero una variable entera que se llame Hermanos y Asigna a la variable casa el valor 3

    Sin embargo en Python no es necesario realizar esta asignación, dado que es un lenguaje con tipado dinámico y, en general, no es necesario definir una variable para poder utilizarla

    En Python escribiríamos directamente La variable hermanos tiene un valor de 2 y sería el interprete quien vería que queremos utilizar una variable que no existe, con el nombre Hermanos y asignarle el valor 2

  • Multi paradigma

    Existen varias formas de programar; con programación orientada a objetos como programación funcional

    Python admite ambos tipos

  • Multi plataforma

    Existen intérpretes de Python para múltiples plataformas, tales como MS Windows, Mac OS o Linux

Tanto el intérprete de Python como su extensa biblioteca estándar están a libre disposición en forma de código fuente y archivo ejecutable para las principales plataformas desde el sitio web de Python

Detrás de Python existe una amplia comunidad que provee amplio soporte a la vez que desarrolla y actualiza constantemente una miriada de librerías centralizado en un repositorio llamado Pypi

Ademas existe un código de buenas prácticas de programación en Python así como una guía de estilo, a fin de que el código sea de fácil lectura y comprensión

Instalación y modos de uso de Python

Python puede instalarse en nuestro ordenador desde la página de Python (recomendado instalar la última versión de Python)

Sin embargo, es más cómodo realizar la instalación mediante una distribución como Anaconda, que nos descarga el intérprete, diferentes editores y los paquetes y librerías más utilizados

Para instalar esta distribución tendríamos que:

  1. Ir a la página de descargas de Anaconda y descargar el paquete que se ajusta a tu sistema operativo y versión de Python deseada

    Se recomienda instalar la correspondiente a la versión más actual de Python

  2. Ejecutar el paquete y dejar que se instale completamente en el sistema
  3. Tras la instalación sería recomendable actualizar los paquetes

    Para ello abre un terminal y ejecuta:

    Mostrará una lista de librerías que van a a ser actualizadas

    Si estás conforme, acepta e iniciará la descarga y la instalación de las librerías

  4. En el caso de querer instalar una librería concreta, en el terminal ejecutaremos:

    Instalará la última versión de la librería presente en el repositorio de Anaconda que corresponda a nuestro sistema operativo y a nuestra versión de Python

En caso de que no esté presente en los repositorios, opcionalmente podemos instalar la librerías con pip

Para ello abre un terminal y ejecuta:

Para más información consultar la documentación de Anaconda

La forma más rápida de utilizar Python es mediante línea de comandos

Una vez tenemos un intérprete instalado en nuestro ordenador, abriríamos un terminal y escribiríamos

Esto abre una consola sobre la que podemos escribir y ejecutar código Python

Cada línea que ejecutásemos se realizaría la operación solicitada

Es una forma muy rápida para testear código pero es muy poco práctica, ya que perdemos la reutilización del código ejecutado

Es decir, si quisiésemos ejecutarlo de nuevo, tendríamos que escribir linea a linea el código otra vez

Lo más común es utilizar un editor como Spyder (se instala junto a Anaconda) o Jupyter notebooks, que es el que voy a utilizar yo para los ejemplos

Jupyter Notebook

Jupyter Notebook (anteriormente, IPython Notebook) es una aplicación web de código abierto que te permite crear y compartir documentos que contienen código en vivo, ecuaciones, visualizaciones y texto narrativo

Además, es una aplicación muy utilizada en el campo de la Ciencia de Datos (Data Science) para crear y compartir documentos que incluyen: limpieza y transformación de datos, simulación numérica, modelado estadístico, visualización de datos, aprendizaje automático y mucho más

Te permite editar y ejecutar documentos de notebook a través de cualquier navegador web de tu elección; y puede ejecutarse en un escritorio local que no requiere acceso a Internet o puede instalarse en un servidor remoto y acceder a través de Internet

También podemos ejecutar Jupyter Notebook sin ninguna instalación desde la página web del proyecto

O instalarlo usando pip, para ello abre un terminal y ejecuta:

Utilizar Jupyter Notebook

Una vez lo tengamos instalado, abriremos un terminal y ejecutaremos:

Esto imprimirá cierta información sobre el servidor de notebook en nuestro terminal, incluida la URL de la aplicación web (de forma predeterminada, http://localhost:8888)

En caso de necesitar conocer la ruta en la que tenemos instalado Jupyter, podemos ejecutar en el terminal:

En caso de necesitar conocer la versión de Python que tenemos instalado, podemos ejecutar en el terminal:

Antes de ejecutar este comando de una línea, se recomienda que verifiquemos que nuestro directorio de Anaconda PATH se haya agregado correctamente a las Variables de entorno, y si no es así, debemos ubicar nuestra ruta de directorio / archivo de Anaconda y agregarlo a las Variables de entorno, o si no podrías obtener un error:

jupyter no se reconoce como un comando interno o externo

Si el lanzamiento ha funcionado correctamente, se abrirá nuestro navegador por defecto con el Notebook abierto en el puerto 8888

Una vez ya dentro del Notebook, observaremos un botón llamado New que, al hacer clic, nos permite seleccionar un kernel de Python (las opciones dependen de lo que esté instalado en nuestro servidor local) del menú desplegable

Se recomienda seleccionar la última versión de Python que nos aparezca en el desplegable, a no ser que sea necesario usar otra por motivos de compatibilidad

Una vez seleccionado y aceptado, se nos abrirá nuestro primer cuaderno para escribir nuestros programas en Python

Nuestro primer script Python

Vamos a escribir un pequeño script de ejemplo para mostrar lo sencillo que es ejecutar un script Python desde Jupyter

Python tiene definido un sistema de almacenamiento y gestión de variables

En las variables podemos guardar información que queramos utilizar más adelante en el código con un nombre que nos sea fácil de recordar

En nuestro ejemplo, queremos calcular el área y el volumen de una esfera

Las ecuaciones que necesitamos son:

  • A = 4\pi \cdot r^2 para el área
  • V = \frac{4}{3}\pi \cdot r^3 para el volumen

En concreto, queremos calcular estos valores para una esfera de 7 de radio

Vamos a definir tres variables:

  • r

    Contiene el valor del radio, en este caso 7

  • A

    Contiene el valor del área calculada

  • V

    Contiene el valor del volumen calculado

¿Qué ventajas obtenemos definiendo variables?

Si cambiamos de idea y en vez de un radio 7 queremos que sea 6, tendríamos que cambiar el número de dos sitios (que en el caso de un programa en producción podrían ser cientos)

O queremos que sea el usuario quien indique el valor, de forma que no podemos saberlo a priori

Para escribirlo en Python usaremos una celda del cuaderno a la que le asignaremos en el menú desplegable (lo veremos a la izquierda del icono que parece un teclado) el valor Code

Una vez dentro de la celda, la usaremos como un editor de texto escribiendo:

Para ejecutarlo podemos usar el botón run o dejando pulsada la tecla de mayúsculas y después pulsando enter

El resultado de las variables permanecerá en memoria, pero nosotros no podremos verlo

Ahora vamos a usar la función print (similar a la función de C++) para poder ver el resultado de nuestro script Python

Para poder usar la constante Pi, se ha importado el módulo math con la sentencia import math y luego la hemos usado con math.pi

Como puede verse, para definir una variable escribimos el nombre con el que queremos bautizarla, el signo = y la expresión que queremos que sea asignada a esa variable

Comentarios en Python

Python soporta comentarios tipo Shell de Unix

Operadores en Python

Operadores en Python

Python posee operadores aritméticos, relacionales, lógicos, bit a bit, de asignación, pertenencia e identidad

Operadores aritméticos

Python suministra las operaciones básicas con los únicos añadidos de los operadores resto, cociente entero y exponenciación

Operadores aritméticos
Operador Operación Descripción
+ Suma Suma dos operandos
Resta

Resta al operando de la izquierda el valor del operando de la derecha

Utilizado sobre un único operando, le cambia el signo

* Multiplicación Multiplicación de dos operandos
/ División Divide el operando de la izquierda por el de la derecha (el resultado siempre es un float)
% Resto Obtiene el resto de dividir el operando de la izquierda por el de la derecha
// Cociente entero Obtiene el cociente entero de dividir el operando de la izquierda por el de la derecha
** Exponenciación El resultado es el operando de la izquierda elevado a la potencia del operando de la derecha

Nota En Python, usar el operador + aplicado a strings, concatena ambas strings en una sola

Operadores relacionales

Se emplean típicamente en las expresiones condicionales

Los operadores relacionales devuelven valores booleanos

Los operandos pueden ser tanto numéricos como strings

Operadores relacionales
Operador Operación Descripción
> Mayor que

True si el operando de la izquierda es estrictamente mayor que el de la derecha

False en caso contrario

< Menor que

True si el operando de la izquierda es estrictamente menor que el de la derecha

False en caso contrario

> = Mayor o igual que

True si el operando de la izquierda es mayor o igual que el de la derecha

False en caso contrario

< = Menor o igual que

True si el operando de la izquierda es menor o igual que el de la derecha

False en caso contrario

! = Distinto que

True si los operandos son distintos

False en caso contrario

= = Igual que

True si el operando de la izquierda es igual que el de la derecha

False en caso contrario

Los objetos de diferentes tipos, excepto los tipos numéricos, nunca se comparan igual

El operador == siempre está definido, pero para algunos tipos de objetos (por ejemplo, objetos de clase) es equivalente a is

Las instancias no idénticas de una clase normalmente se comparan como no iguales a menos que la clase defina el método __eq__()

Las instancias de una clase no se pueden ordenar con respecto a otras instancias de la misma clase u otros tipos de objeto, a menos que la clase defina los métodos __lt__() y __gt__()

Operadores lógicos

Los operandos lógicos está relacionados con los relacionales ya que normalmente los operandos que usan son resultado de expresiones relacionales

Los valores resultantes son booleanos

Operadores lógicos
Operador Descripción
AND True si ambos son True
OR True si uno de ellos es True
NOT Si era True pasa a False y viceversa

Operadores bit a bit

La forma de trabajar de estos operadores es convertir a binario los operandos y luego operar con ellos bit a bit

Operadores bit a bit
Operador Operación Descripción
& AND Cambia el bit a 1 si ambos eran 1
| OR Cambia el bit a 1 si uno de ellos era 1
^ XOR Cambia el bit a 1 si uno de ellos era 1, pero no ambos
~ NOT

Cambia el bit a 1 si era 0

Cambia el bit a 0 si era 1

<< Propagación a la izquierda Desplaza el valor hacia la izquierda introduciendo ceros, si se sale de rango se pierden valores
>> Propagación a la derecha Desplaza el valor hacia la derecha introduciendo por la izquierda el bit de signo y eliminando los valores que se salgan por la derecha

Nota Los operadores de propagación toman dos operandos: el primero es la variable a propagar y el segundo es el número de posiciones a propagar

Operadores de asignación

La asignación también es un operador que devuelve la variable modificada

El operador de asignación en Python es =

Los operadores de asignación que se muestran a continuación no son sino abreviaturas que hacen más cómoda y simples las expresiones, aunque a veces sean más ilegibles

Operadores de asignación
Operador Expresión Equivalencia
=

A = B = C

D = ‘Texto’

A = C

B = C

D = ‘Texto’

+ = A + = 4 A = A + 4
– = A – = 3 * B A = A – (3 * B)
* = A * = 2 A = A * 2
** = A ** = 2 A = A ** 2
/ = A / = 35 + B A = A / (35 + B)
% = A % = B A = A % B
// = A // = B A = A // B
>> = A >> = 1 A = A >> 1
<< = A << = B A = A << B
& = A & = (C + = 3) C = C +3
A = A & C
^ = A ^ = 2 A = A ^ 2
| = A | = C A = A | C

Operadores de pertenencia

Los operadores de pertenencia se utilizan para comprobar si un valor o variable se encuentran en una secuencia (list, tuple, dict, set o str)

Operadores de pertenencia
Operador Expresión Equivalencia
in Incluido

Devuelve True si el valor se encuentra en una secuencia

False en caso contrario

not in No incluido

Devuelve True si el valor no se encuentra en una secuencia

False en caso contrario

Operadores de identidad

Estos operadores se van a utilizar para comprobar si dos variables son, o no, el mismo objeto

Operadores de pertenencia
Operador Expresión Equivalencia
is Objetos iguales

Devuelve True si ambos operandos hacen referencia al mismo objeto

False en caso contrario

is not Objetos distintos

Devuelve True si ambos operandos no hacen referencia al mismo objeto

False en caso contrario

Preferencia

La preferencia de los operadores va a determinar el orden en que se ejecuten en una expresión determinada

Usando paréntesis controlaremos que las operaciones se lleven a cabo según nosotros queramos

En Python la preferencia de los operadores de mayor a menor es la siguiente:

Preferencia
Paréntesis ( )
Exponenciación **
Unarios ~ +
Mul / Div / Resto / Div ent * / % //
Suma / Resta +
Propagación << >>
Bit a bit &
Bit a bit ^ |
Relacionales < < = > > =
Igualdad = = !=
Asignación = + = – = * = * * = / = // = % = & = | = ^ = >> = << =
Identidad is is not
Pertenencia in not in

Tipos de datos en Python

Tipos de datos en Python

Los tipos en Python son una representación de los datos, ya que no requiere que las variables declaren su tipo, porque todos los tipos se convierten de forma automática

Podemos utilizar la función type para conocer el tipo de una variable

Tipo booleano

El tipo booleano simplemente distingue entre dos estados, un estado de éxito o de activado, valor verdadero, True, y un estado de fracaso o de desactivado, valor falso, False

Ambos estados no son susceptibles a mayúsculas y minúsculas

Normalmente, el resultado de operadores que devuelven un valor de tipo booleano son pasados a las estructura de control

Tipos numéricos

En Python existen 4 tipos diferentes de variables numéricas:

  • int

    número entero con precisión fija

  • long

    número entero en caso de sobrepasar el tamaño de un int

  • float

    número en coma flotante de doble precisión

  • complex

    número complejo (parte real + j parte imaginaria)

Es el intérprete el que decide el tipo de variable según lo que definimos

Sin embargo, podemos querer forzarlo nosotros mediante un cast

Tipo string

Un string es una cadena de caracteres delimitadas por comillas

Un literal de tipo string se puede especificar de dos formas diferentes:

  • entrecomillado simple

    se especifican entre los carácteres de apertura y de cierre

    Para especificar una comilla simple literal, se ha de escapar con una barra invertida (\). Para especificar una barra invertida literal, se duplica (\\)

    Todas las demás instancias de barras invertidas serán tratadas como una barra invertida literal: esto significa que otras secuencias de escape que podrían utilizarse, tales como \r o \n, serán mostradas literalmente tal y como se especifican, en lugar de tener cualquier otro significado especial

  • entrecomillado doble

    se especifican entre los carácteres " de apertura y " de cierre

    Python interpretará las siguientes secuencias de escape como caracteres especiales:

    Código Descripción
    \n avance de línea (LF o 0x0A (10) en ASCII)
    \r retorno de carro (CR o 0x0D (13) en ASCII)
    \t tabulador horizontal (HT o 0x09 (9) en ASCII)
    \\ barra invertida
    \" comillas dobles

Métodos

Vamos a ver algunos de los métodos para cadenas de uso más cotidiano

Métodos de formato

Afectan al formato del texto contenido en la cadena

  • capitalize()

    Realiza una copia de la cadena con la primera letra en mayúsculas

  • lower()

    Devuelve una copia de la cadena en minúsculas

  • upper()

    Devuelve una copia de la cadena en mayúsculas

  • swapcase()

    Devuelve una copia de la cadena en la que las mayúsculas son minúsculas y viceversa

  • title()

    Devuelve una copia de la cadena en la que la primera letra de cada palabra es mayúscula y las demás minúsculas

  • center(longitud, ‘caracter de relleno’)

    Devuelve una copia de la cadena de entrada centrada en la longitud indicada y entre el caracter de relleno que se indique

  • ljust(longitud, ‘caracter de relleno’): Devuelve una copia de la cadena alineada a la izquierda

  • rjust(longitud, ‘caracter de relleno’)

    Devuelve una copia de la cadena alineada a la izda/derecha

  • zfill(longitud)

    Devuelve una copia de la cadena rellenada con ceros a la izda hasta alcanzar la longitud indicada

Métodos de búsqueda

Nos permiten buscar dentro de una determinada cadena para comprobar si una subcadena está contenida en la cadena o cuántas veces aparece una subcadena

  • count(‘subcadena’)

    Devuelve un entero representando la cantidad de apariciones de la subcadena dentro de la cadena

  • find(‘subcadena’)

    Devuelve un entero representando la posición en la que empieza la subcadena dentro de la cadena

Métodos de validación

Nos devuelven siempre un booleano, es decir, True o False

Sirven para comprobar si una cadena cumple una determinada condición

  • startswith(‘subcadena’)

    Nos dice si una cadena comienza por una cadena determinada

  • endswith(‘subcadena’)

    Nos dice si una cadena termina por una cadena determinada

  • isalnum()

    Nos dice si una subcadena es alfanumérica

  • isalpha()

    Nos dice si una cadena es alfabética

  • isdigit()

    Nos dice si una cadena es numértica

  • islower()

    Nos dice si una cadena contiene sólo minúsculas

  • isupper()

    Nos dice si una cadena contiene sólo mayúsculas

  • isspace()

    Nos dice si una cadena contiene sólo espacios en blanco

  • istitle()

    Nos dice si una cadena tiene formato de título

Métodos de sustitución

Nos permiten sustituir texto para unificar el formato de diferentes cadenas que nos han llegado por vías diferentes

  • format(argumentos)

    Podemos tener una cadena que esté preparada para recibir una cierta cantidad de argumentos

    Al llamar a esta función e introducir los argumentos necesarios nos devuelve una copia de la cadena ya formateada

  • replace(‘subcadena buscada’, ‘subcadena que poner’)

    Busca dentro de la cadena una subcadena y la sustituye por la cadena indicada

  • strip()

    Elimina el carácter que indiquemos de la derecha y de la izquierda de la cadena

    Por defecto busca el carácter espacio

  • lstrip()

    Elimina los caracteres a la izquierda de una cadena

    Si introducimos como argumento una subcadena, busca esa subcadena y las combinaciones de los caracteres de la subcadena desde la izquierda hasta que no encuentre ninguno más

  • rstrip()

    Elimina los caracteres a la a derecha de una cadena

    Si introducimos como argumento una subcadena, busca esa subcadena y las combinaciones de los caracteres de la subcadena desde la derecha hasta que no encuentre ninguno más

Métodos de unión y división

Nos permiten sustituir texto para unificar diferentes cadenas que nos han llegado por vías diferentes o para separar una cadena en varias

  • join(iterable)

    Recibe como argumento un iterable y devuelve como resultado los elementos del iterable unidos por el carácter de la cadena sobre la que se aplica

  • partition(‘separador’)

    Devuelve una tupla de 3 elementos

    El primer elemento es lo que hay a la izquierda del ‘separador’, el segundo elemento es el separador y el tercer elemento es lo que hay a la derecha del separador

  • split(‘separador’)

    Devuelve una lista con todos los elementos encontrados al dividir la cadena por el separador

  • splitlines()

    Devuelve una lista donde cada elemento es una fracción de la cadena dividida en líneas

Listas

Se definen poniendo el contenido de la lista entre corchetes, separando cada uno de los elementos mediante una coma

Cada posición de la lista puede contener elementos de distinto tipo

Las listas son mutables, es decir, sus elementos pueden ser modificados

En Python los elementos de una lista se numeran desde 0 hasta longitud – 1

Para acceder al elemento de una lista se pone el nombre de la lista y a continuación el índice al que queremos acceder (si ponemos el índice con signo negativo empezará por el final de la lista)

Para acceder a un rango dentro de una lista tenemos diferentes opciones:

  • Tomar elementos desde el inicio: lista[:a]
  • Tomar elementos desde la posición a (incluida) hasta el final: lista[a:]
  • Tomar elementos desde a hasta b (sin incluir b): lista[a:b]

El inicio del rango siempre incluye el elemento en esa posición, pero no el final del rango

Métodos

Vamos a ver algunos de los métodos para listas de uso más cotidiano

  • append()

    añade un elemento al final de la lista

  • insert()

    se usa para insertar un elemento en el índice asignado

  • pop()

    elimina y devuelve el valor en la posición del índice asignado

  • reverse()

    reordena la lista de forma reversa

  • sort()

    reordena la lista de forma ascendente

Podemos encontrar todos los métodos en su documentación

Tuplas

Las tuplas son similares a las listas, se definen con paréntesis en vez de corchetes

Tienen la peculiaridad de ser inmutables

Como puede verse, se accede a los elementos de igual forma que con las listas

Diccionarios

Los diccionarios definen una relación de uno a uno entre clave valor entre {} y son mutables

Se definen colocando una lista separada por comas de pares clave:valor

Una vez definido, podemos acceder al valor asociado a una clave buscando por clave

Además, podemos buscar si una determinada clave existe o no en nuestro diccionario

Los diccionarios son un tipo de colección en Python que, a diferencia de las listas, están indexadas por palabras y no por números

Los valores pueden ser de cualquier tipo

Podemos pensar en un diccionario como un conjunto no ordenado de pares clave:valor con el requisito de que las claves tienen que ser únicas

Métodos

Vamos a ver algunos de los métodos para diccionarios de uso más cotidiano

  • keys()

    nos devuelve un iterable que contiene las claves del diccionario

  • values()

    nos devuelve un iterable que contiene los valores del diccionario

  • items()

    nos devuelve un iterable con los pares clave:valor del diccionario

Objetos

Los objetos se componen de un conjunto de valores, propiedades y un conjunto de métodos aplicados a esos valores

Son estos métodos los que nos permiten modificar el estado de dicho objeto, es decir, el valor de sus propiedades

En Python los objetos tiene las siguientes particularidades:

  • Todo es un objeto, incluyendo los tipos y clases
  • Permite herencia múltiple
  • No existen métodos ni atributos privados
  • Los atributos pueden ser modificados directamente
  • Permite monkey patching

    Las clases se crean en tiempo de ejecución pero pueden modificarse tras ser creadas

  • Permite duck typing

    El estilo de tipificación dinámica de datos en que el conjunto actual de métodos y propiedades determina la validez semántica, en vez de que lo hagan la herencia de una clase

  • Permite la sobrecarga de operadores
  • Permite la creación de nuevos tipos de datos

Vamos a crear un objeto Universitario de ejemplo en el que tendremos las propiedades: Nombre, Apellido, Edad y Dni

La instancia del objeto la crearemos mediante la asignación a una variable de la siguiente forma:

Es posible consultar la clase de un objeto con la función type, pero también se puede consultar a través de su atributo especial __class__

A su vez las clases tienen un atributo especial __name__ que nos devuelve su nombre en forma de cadena sin adornos:

Es posible inicializar todas las variables para que tengan el tipo que queremos, para ello usaremos el constructor de la clase pasándole los argumentos que necesitemos

El constructor es un método que se llama automáticamente al crear un objeto y se define con el nombre __init__ y mediante la palabra reservada self podremos referenciar al objeto actual

Si existe un constructor también debe existir un destructor que se llame al eliminar el objeto para que encargue de las tareas de limpieza como vaciar la memoria

Todos los objetos se borran automáticamente de la memoria al finalizar el programa, aunque para eliminarlos automáticamente disponemos del método especial __del__

No es aconsejable sobreescribir este método porque se maneja automáticamente, pero es interesante saber que es posible

El método __str__ es el que devuelve la representación de un objeto en forma de cadena

Se llama automáticamente es cuando imprimirmos una variable por pantalla con la función print

Por defecto los objetos imprimen su clase y una dirección de memoria, pero podemos cambiarlo sobreescribiendo su comportamiento

Por ejemplo, para el objeto universitario sobreescribimos el método __str__ para que nos muestre el nombre, edad, apellidos y dni

Un método especial interesante es el que devuelve la longitud

Normalmente está ligado a colecciones, pero nada impide definirlo en una clase y no redefinirlo, porque por defecto no existe en los objetos aunque sea el que se ejecuta al pasarlos a la función __len__

En nuestro ejemplo del objeto universitario no tiene mucho sentido contar su longitud, pero lo incluyo para mostrar su uso

Las propiedades de un objeto pueden describirse mediante otros objetos o incluso colecciones de ellos

La definición de métodos asociados a un objeto puede precisarse en la definición del objeto

Por ejemplo, para el objeto universitario sobreescribimos el método __str__ para que muestre el nombre, edad, apellidos, dni y notas medias del alumno

Para acceder a las propiedades o a los métodos usaremos el operador .

Herencia

La herencia es la capacidad que tiene una clase de heredar los atributos y métodos de otra, algo que nos permite reutilizar código

Para ver su utilidad, vamos a desarrollar un ejemplo modificando el objeto universidad

Partiremos de una clase base que hará de padre (superclase) de otras hijas que heredaran de ella (subclases)

Partimos de una clase Persona que contendrá todos los atributos comunes y dos clases hijas Alumno y Profesor que heredan de ella y tienen atributos o métodos propios

Para heredar los atributos y métodos de una clase en otra sólo tenemos que pasarla entre paréntesis durante su definición

Es posible utilizar el comportamiento de una superclase sin definir nada en la subclase, aunque en nuestro ejemplo si que les daremos comportamiento

Gracias a la flexibilidad de Python podemos manejar objetos de distintas clases masivamente de una forma muy simple

Vamos a empezar creando una lista con nuestros dos Personas de subclases distintas

Uno de los pocos fallos de Python es que si modificamos los valores dentro de un objeto, estos cambios se verán reflejados fuera del mismo

De la misma forma que en las colecciones, los objetos se pasan a las funciones por referencia

Afecta a la hora de hacer copias, creándose en su lugar un acceso al objeto en lugar de uno nuevo con sus valores anteriores

Para realizar una copia a partir de sus valores podemos utilizar la función copy del módulo con el mismo nombre

La función copy se puede utilizar también para copiar colecciones

La herencia múltiple permite a una subclase heredar de múltiples superclases

Esto conlleva un problema, y es que si varias superclases tienen los mismos atributos o métodos, la subclase sólo podrá heredar de una de ellas

Además de superclases también puede heredar de forma múltiple de subclases

En estos casos Python dará prioridad a las clases más a la izquierda en el momento de la declaración de la subclase

Hemos usado la palabra reservada pass para indicarle al intérprete que ignore el código del cuerpo y utilice el de la clase object o el de las superclases (subclases) que le indiquemos

Valor nulo

En Python a las variables se les puede asignar un valor que indica el valor vacío, este valor es el valor NULL

Una variable es considerada None si:

  • se le ha asignado la constante None
  • no se le ha pasado un atributo a una función

La constante None es insensible a mayúsculas o minúsculas

Estructuras de control en Python

Estructuras de control en Python

Para las estructuras de control, Python posee las sentencias de control típicas de los lenguajes de alto nivel

Declaración de variables

A las variables en Python no se les asigna un tipo predefinido

En Python el tipo de las variables depende del valor que contengan las mismas en cada momento

Por tanto se realiza una conversión automática de tipos

Python reconoce los siguientes tipos de valores:

  • Números
  • Valores booleanos

    true y false

  • Strings
  • Listas

    tipo de datos que asocia valores con un valor numérico poniendo el contenido de la lista entre corchetes, separando cada uno de los elementos mediante una coma

  • Tuplas

    tipo de datos que asocia valores con un valor numérico poniendo el contenido de la lista entre paréntesis, separando cada uno de los elementos mediante una coma

    Tienen la peculiaridad de ser inmutables

  • Diccionarios

    tipo de datos que asocia un valor a una clave y permite buscar por esas claves

  • Objetos

    Creados por el programador o predefinidos por el lenguaje

Al tratarse de un lenguaje con tipado dinámico, no es necesario decirle al intérprete su tipo de variable, sino que es él quien decide el tipo que asignará

Los nombres con los que podemos nombrar variables en Python siguen varias normas:

  • Los nombres empiezan siempre por letra
  • Dentro del nombre se puede usar cualquier letra o número dentro de la codificación utf-8
  • No se pueden usar las palabras reservadas de Python, que son usadas en su sintaxis de su código

    Para más información sobre estos nombres consultar en la documentación de Python

Notar que Python distingue entre mayúsculas y minúsculas, por lo que dos variables con el mismo nombre pero que contenga una letra en mayúscula serán entendidas como dos variables distintas

Por ejemplo Variable es diferente de variable

Además existen ciertos convenios para reducir errores y mejorar la legibilidad

Para evitar errores se recomienda no usar ciertos caracteres:

  • No usar ni l (ele minúscula) ni I (i mayuscula), ya que dependiendo del tipo de fuente que se use pueden confundirse entre si o con el número 1
  • No usar O (o mayúscula) ya que dependiendo del tipo de fuente que se use puede llevar a confusión con el número 0

A fin de favorecer la legibilidad se hacen las siguientes sugerencias:

  • nombredevarible es poco legible, por estar todo junto y puede dificultar su legibilidad
  • nombreDeVarible es un poco más legible, al aplicar letra mayúscula al iniciar palabra
  • nombre_de_variable es la que mejor legibilidad aporta, al aplicar guión bajo al iniciar palabra, que es la forma más recomendada

La sentencia if

La sentencia if tiene la forma:

En caso de que la condición sea verdadera se ejecutará la instrucción 1; en caso contrario se ejecuta si existe la instrucción 2

El uso de la sentencia else es opcional, por eso en la definición se han utilizado los corchetes

Si se omite, sólo se tendrá en cuenta el bloque de instrucciones cuando la condición sea verdadera

Un bloque de instrucciones es un conjunto de instrucciones tabulaciones después de la sentencia if, al saltar de línea después del símbolo :

Son obligatorias ya que le dicen al interprete que el bloque de instrucciones pertenece a la sentencia if

Si se omiten y la condición era verdadera, se ejecutará la siguiente instrucción

En caso contrario, se ejecutará la subsiguiente instrucción, de forma independiente al estado de la condición

De este modo, la omisión de las tabulaciones después de la sentencia if nos permitirá escribirlo todo en una única línea después del símbolo :

La sentencia elif

También podemos utilizar sentencias if anidades mediante la sentencia elif

Las sentencias elif funcionan igual que una sentencia if

Pero sólo se ejecutarán en caso de que la condición de la sentencia if fuese falsa

Podemos añadir opcionalmente una sentencia else al final pero sólo se ejecutará si todas las condiciones anteriores fuesen falsas

La sentencia while

La sentencia while tiene la forma

Si se cumple la condición, se ejecuta la instrucción o el bloque de instrucciones y se repite el proceso hasta que deje de cumplirse la condición

La sentencia for

Este bucle, tiene una sintaxis muy parecida al for-each de Java

Itera una variable var sobre todas las propiedades de un objeto obj que se le pasa

Así para cada valor de var se ejecutaran las sentencias del bucle

Por lo tanto, el bucle tendrá tantas iteraciones como propiedades el objeto y en cada iteración la variable tendrá el valor de la propiedad del objeto correspondiente con dicha iteración

Su sintaxis es:

Iteradores

En Python existen diferentes estructuras que son conjuntos de elementos, son las llamadas colecciones

Este tipo de estructuras son iterables, es decir, se pueden recorrer elemento por elemento

Algunos tipos de variable que son iterables son:

  • Cadena de caracteres (str)
  • Lista (list)
  • Tupla (tuple)
  • Diccionario (dict)

Su uso es útil para recorrer elementos de colección como las listas, las tuplas o los objetos

Además, muchas veces queremos repetir un bucle un número determinado de veces

Para esto puede ser útil la función range(n)

Esta función genera un iterable que va desde 0 hasta n – 1

La sentencia break

La sentencia break se puede colocar dentro de un bucle o bucles anidados

Cuando se ejecuta la sentencia break se abandona el bucle más interno

A todos los efectos la sentencia break actúa como un salto a la instrucción siguiente al bucle en el que se ejecuta

La sentencia continue

La sentencia continue, no abandona el bucle si no que hace que se ejecute la siguiente iteración

En el bucle while la ejecución del continue hace que el flujo del programa salte a la condición

En el bucle for la ejecución del continue hace que se ejecute la expresión de incremento, para después continuar normalmente con la condición

Es decir, la ejecución del continue evita que se ejecute el resto del cuerpo del bucle

Funciones en Python

Funciones en Python

Para definir funciones en Python disponemos de la instrucción def

Después de esta palabra reservada va el nombre de la función junto con una lista de argumentos delimitados por paréntesis y separados por comas, finalizando con el símbolo :

La definición de una función no ejecuta el cuerpo de la función

Solamente será ejecutada cuando la función sea llamada

Su ejecución enlaza el nombre de la función con el namespace local actual a un objecto función (un envoltorio alrededor del código ejecutable para la función)

Este objeto función contiene una referencia al namespace local global como el namespace global para ser usado cuando la función sea llamada

De forma opcional puede añadirse una expresión que será devuelta por la función

La expresión puede será un tipo válido de Python precedida por la sentencia return

El DOCSTRING es un texto descriptivo de la función encerrado entre tres comillas dobles de apertura y cierre, antes de la primera instrucción

Es opcional, así que si no queremos añadir una descripción, podemos omitirlo

Pero se recomienda su uso para que cuando revisemos después de un tiempo nuestro código, recordemos qué hacía nuestra función

Argumentos

El paso de argumentos es opcional y en algunos casos puede haber funciones que carezcan de ellos

Tipo de los argumentos

Admite los tipos str, int, float, complex,bool, list, tuple, dic y class

Argumentos con valor por posición

Cuando enviamos argumentos a una función, estos se reciben por orden en los parámetros definidos

Argumentos con valor por nombre

Es posible evadir el orden de los parámetros si indicamos durante la llamada el valor que tiene cada parámetro a partir de su nombre

Sin Argumentos

Al momento de llamar una función la cual tiene definidos unos parámetros, si no pasa los argumentos correctamente provocará una excepción TypeError

Argumentos con valor por defecto

En ocasiones necesitamos que un argumento tenga un valor, para evitar un error (que provocaría el lanzamiento de la excepción TypeError), aunque el usuario de la función no lo introduzca

Hay que tener en cuenta, que los argumentos con valor por defecto pasan a ser opcionales y que todos los argumentos a la izquierda del primer valor por defecto, son obligatorios

En el ejemplo se ha utilizado el valor nulo (None) para expresar que no se habían pasado argumentos

Pero podríamos utilizar cualquier tipo que precisemos como valor por defecto

Argumentos indeterminados

En algunas ocasiones no sabremos previamente cuantos elementos necesitamos enviar a una función

Para estos casos podemos utilizar los parámetros indeterminados por posición o por nombre

Argumentos por posición

Como argumento usaremos un tipo tuple precediendolo con el símbolo *

De esta forma todos los argumentos serán recibidos por posición, pudiendo recorrerlos cómodamente con un bucle for

Argumentos por nombre

Como argumento usaremos un tipo dict precediendolo con los símbolos **

De esta forma todos los argumentos serán recibidos por el nombre de la clave del diccionario, pudiendo recorrerlos cómodamente con un bucle for

Argumentos por posición y nombre

En alguna ocasión puede necesitar utilizar ambos tipos de parámetros simultáneamente en una función, entonces debe crear ambas colecciones dinámicas

Primero los argumentos indeterminados por valor y luego por nombre

En todos los ejemplos se han utilizado los nombres args y kwargs pero no son obligatorios

Muchos frameworks y librerías los utilizan por lo que es una buena practica llamarlos así, por convención

La sentencia pass

Es una operación nula, cuando la ejecutamos, parece que nada sucede

Es útil como un contenedor cuando una sentencia es requerida sintácticamente, pero no es necesario ejecutar código

La sentencia return

La sentencia return es la que permite devolver el resultado de una función

Admite los tipos str, int, float, complex,bool, list, tuple, dic y class

La setencia return es opcional, pero si se omite, por defecto devolverá el valor nulo (None)

Retorno múltiple

Una característica interesante de las funciones en Python, es la posibilidad de devolver valores múltiples separados por comas

Funciones predefinidas por el lenguaje

Las funciones predefinidas por el lenguaje están ordenadas por módulos

Un módulo es un conjunto de clases y funciones almacenadas en un archivo que pueden ser utilizadas posteriormente

Podemos crear nuestros propios módulos e importarlos a los nuevos programas que hagamos

Sin embargo, es aconsejable reutilizar los módulos ya existentes

Para importar un módulo utilizaremos la sentencia import

De esta forma estaremos manejando un namespace, de forma similar a como lo hace C++ (using namespaces) o Java

Que tiene la siguiente sintaxis

Para llamar a una función concreta del módulo utilizaremos nombre.funcion() o alias.funcion en caso de que le hayamos dado un alias al módulo

En caso de no querer utilizar todas la funciones del módulo pero si una concreta, utilizaremos la sentencia from

Que tiene la siguiente sintaxis

Módulo sys

Este módulo es el encargado de proveer variables y funcionalidades relacionadas con el intérprete

Las variables del módulo sys son:

  • sys.executable

    Retorna el directorio absoluto del archivo binario ejecutable del intérprete de Python

  • sys.platform

    Retorna la plataforma sobre la cual se está ejecutando el intérprete

  • sys.version

    Retorna el número de versión de Python con información adicional

Los métodos más destacados del módulo sys son los siguientes:

  • sys.exit()

    Forzar la salida del intérprete

  • sys.getdefaultencoding()

    Retorna la codificación de caracteres por defecto

  • sys.getfilesystemencoding()

    Retorna la codificación de caracteres que se utiliza para convertir los nombres de archivos unicode en nombres de archivos del sistema

  • sys.getsizeof()

    Retorna el tamaño del objeto pasado como parámetro

Módulo os

Este módulo nos permite acceder a funcionalidades dependientes del SO

Sobre todo, aquellas que nos dan información sobre el entorno del mismo y nos permiten manipular la estructura de directorios

Algunos de los métodos más utilizados son:

  • os.getcwd()

    Nos informa de cuál es el directorio actual

  • os.chdir(ruta)

    Cambia el directorio de trabajo a la ruta pasada como argumento

  • os.chroot()

    Cambia al directorio raiz

  • os.mkdir(directorio)

    Crea el directorio pasado como argumento

  • os.rmdir(directorio)

    Elimina el directorio pasado como argumento

  • os.remove(fichero)

    Eliminar el archivo pasado como argumento

  • os.rename(actual, nuevo)

    Renombra el archivo actual por el nombre del archivo nuevo, pasados como argumentos

Módulo math

Este módulo nos provee de funciones y constantes matemáticas

Podemos encontrar todas las funciones y atributos en su documentación

Algunas de los variables más utilizadas son:

  • math.pi

    Representa el valor de la variable \pi (número Pi)

  • math.e

    Representa el valor de la variable e (número de Euler o constante de Napier)

  • math.tau

    Representa el valor de la variable \tau = 2\cdot\pi (constante Tau, propuesta por Bob Palais, Peter Harremoes, Hermann Laurent, Fred Hoyle, Michael Hartl, Nicolás Atanes, entre otros)

Algunos de los métodos más utilizados son:

  • math.ceil(x)

    Devuelve el entero menor que sea mayor o igual que x

  • math.floor(x)

    Devuelve el entero mayor menor o igual a x

  • math.exp(x)

    Devuelve el número e elevado a la potencia x

  • math.log2(x)

    Devuelve el logaritmo en base 2 de x

  • math.sin(x)

    Devuelve el seno de x radianes

  • math.cos(x)

    Devuelve el coseno de x radianes

  • math.tan(x)

    Devuelve la tangente de x radianes

  • math.degrees(x)

    Convierte el ángulo x de radianes a grados

Módulo random

El módulo random se utiliza para todo lo relacionado con números aleatorios

Algunos de los métodos más utilizados son:

  • shuffle(col)

    Reordena aleatoriamente los elementos de una colección

  • sample(col, k)

    Toma n elementos sin reemplazo de una coleccion

  • random()

    Genera un número aleatorio en el intervalo [0, 1)

  • uniform(a, b)

    Genera un número aleatorio en el intervalo [a, b]

  • randint(a, b)

    Genera un número aleatorio entero en el intervalo [a, b]

  • gauss(media, sigma)

    Genera un número aleatorio siguiendo una distribución gaussiana con media y sigma dadas

Módulo NumPy

Numpy nos proporciona una gran cantidad de funciones matemáticas y el tipo de variable NumPy array

Por lo general el paquete NumPy suele importarse con el alias np

Este módulo nos permite trabajar con estructuras matemáticas de una forma muy cómoda (producto de matrices, números aleatorios, operaciones sobre matrices…)

Es un módulo que no viene instalado por defecto

Para ello abre un terminal y ejecuta:

Podemos encontrar todas las funciones y atributos en su documentación

Algunos de los métodos más utilizados son:

  • random.rand()

    Nos devuelve valores aleatorios con la forma deseada

  • empty()

    Crea un array vacío con la forma indicada

  • zeros()

    Crea un array de ceros con la forma indicada

  • dot()

    Calcula el producto matricial entre dos arrays

  • sum()

    Calcula la suma de los elementos de un array

Módulo Pandas

El paquete pandas es muy utilizado en el Data Scientists

Es uno de los paquetes sobre el que deberíamos centrarnos para aprender sobre análisis de datos

A través de pandas podemos familiarizarnos con nuestro set de datos limpiándolo, transformándolo y analizándolo

Por ejemplo, con pandas podemos leer un fichero CSV de nuestro ordenador, pasarlo a un DataFrame (una tabla, en esencia) y hacer cosas como:

  • Calcular estadísticas y responder preguntas sobre los datos como sacar el máximo, minimo y media de cada columna, saber cómo de correlacionadas están las columnas A y B o conocer la distribución estadística de la columna C
  • Limpiar los datos haciendo cosas como eliminar los valores faltantes o filtrando filas y columnas de acuerdo a algún criterio
  • Visualizar los datos con la ayuda de matplotlib
  • Guardar los datos ya limpiados de vuelta en un CSV o una base de datos
  • Pandas se basa en NumPy, por lo que debemos tener ese módulo instalado previamente

    Jupyter Notebooks es una aplicación que se complementa muy bien con Pandas, ya que podemos ejecutar el código por celdas en vez que de forma completa, lo cual es útil si trabajamos con grandes datasets

    Los componentes primarios de Pandas son series y DataFrame, siendo el primer tipo una columna y el segundo una table

    Por lo general el paquete pandas suele importarse con el alias np

    Es un módulo que no viene instalado por defecto

    Para ello abre un terminal y ejecuta:

    Podemos encontrar todas las funciones y atributos en su documentación

    Ahora vamos a crear un ejemplo sencillo para mostrar el uso de pandas usando una serie que contendrá a los integrantes de la selección Española de fútbol que ganó el mundial del año 2010

    Para crear la serie utilizamos el método pd.Series que recibirá una lista con los nombres de los jugadores y una lista con el número de dorsal de los jugadores

    Después lo mostraremos por pantalla

    Ahora no le vamos a indicar los índices de forma explícita, entonces generará los índices de forma automática empezando desde el valor cero

    Ahora vamos a introducir en la serie un diccionario en vez de una lista y le vamos a añadir un jugador más

    Ahora vamos a crear un ejemplo sencillo para mostrar el uso de pandas usando un DataFrame que contendrá a los integrantes de la selección Española de fútbol que ganó el mundial del año 2010

    Para crear el DataFrame utilizamos el método pd.DataFrame que recibirá un diccionario con los datos de los jugadores, una lista con el nombre de la columna y una lista con el número de dorsal de los jugadores

    Añadiremos un jugador más utilizando el método loc del objeto DataFrame

    Después lo mostraremos por pantalla

    Funciones de visualización

    print

    La función print sirve para enviar la salida de sus argumentos al navegador con un formato

    Operador %

    El operador % también se puede utilizar para el formato de la cadena

    Interpreta el argumento izquierdo de manera muy parecida a una cadena de formato de estilo de la función printf de C++, que se aplica al argumento derecho

    En Python, no hay una función printf pero se le ha dotado de su funcionalidad a print

    Para este propósito, el operador % está sobrecargado para cadenas para mostrar el formato de la cadena

    A menudo se le llama operador de módulo de cadena (o, a veces, incluso, módulo)

    Tiene el formato:

    Para formatear un texto deberemos introducir los siguientes caracteres de formato precedidos por el símbolo %:

    Caracteres de formato para texto
    Caracter Descripción
    c

    El argumento es tratado como un valor de tipo string y recoge un único carácter

    d

    El argumento es tratado como un valor de tipo int y presentado como un número entero

    e

    El argumento es tratado con notación científica (por ejemplo 1.2e+2)

    E

    Como %e pero utiliza la letra mayúscula (por ejemplo 1.2E+2)

    f

    El argumento es tratado como un valor de tipo float y presentado como un número de punto flotante (considerando la configuración regional)

    F

    El argumento es tratado como un valor de tipo float y presentado como un número de punto flotante (sin considerar la configuración regional)

    g

    Igual que %e y %f

    G

    Igual que %E y %f

    o

    El argumento es tratado como un valor de tipo integer y presentado como un número octal

    s

    El argumento es tratado como un valor de tipo string y recoge una cadena de caracteres

    u

    El argumento es tratado como un valor de tipo int y presentado como un número decimal sin signo

    x

    El argumento es tratado como un valor de tipo integer y presentado como un número hexadecimal

    X

    El argumento es tratado como un valor de tipo integer y presentado como un número hexadecimal en mayúsculas

    Método format

    El método format se añadió a los tipos string en Python 2.6

    Permite el uso de los caracteres {} para marcar dónde se sustituirá una variable y utiliza directivas de formato detalladas usadas para formatear

    Este método nos permite concatenar elementos dentro de una salida a través del formato posicional

    Los corchetes y los caracteres dentro de ellos (llamados campos de formato) se reemplazan con los objetos pasados al método format

    Se puede usar un número entre paréntesis para referirse a la posición del argumento pasado al método format

    Hay que tener en cuenta que el primer argumento empieza en cero

    También se puede usar un identificador clave cuando el argumento sea pasado por nombre

    Esta opción nos será útil cuando trabajemos con diccionarios o cuando queramos reducir algo el código

    Opcionalmente se puede poner el símbolo : después del número o nombre, y explicitar el tipo del objeto:

    Caracteres de formato para texto
    Caracter Descripción
    s

    El argumento es tratado como un valor de tipo string y recoge una cadena de caracteres

    d

    El argumento es tratado como un valor de tipo int y presentado como un número decimal (con signo)

    f

    El argumento es tratado como un valor de tipo float y presentado como un número de punto flotante (considerando la configuración regional)

    Funciones de orden superior

    En matemáticas y ciencias de la computación, las funciones de orden superior son funciones que cumplen al menos una de las siguientes condiciones:

    • Tomar una o más funciones como entrada
    • Devolver una función como salida

    Funciones lambda

    Las funciones lambda son funciones anónimas, es decir, funciones sin nombre

    Sólo se utilizan en el lugar en el que se han creado (aunque se les puede asignar un nombre y usarlas más adelante)

    Se utilizan por lo general junto a las funciones map, filter y reduce

    Por lo general se utilizan para crear funciones que son pasadas como argumentos a otras funciones

    En Python la sintaxis de una función lamdba es:

    Donde la expresión puede ser cualquier operación que haríamos al realizar una asignación

    Funcion map

    Nos permite aplicar una función sobre cada uno de los elementos de un iterable

    Nos devuelve un map object, que podemos transformar fácilmente en una lista

    Funcion filter

    Nos permite filtrar los elementos de una colección (por ejemplo una lista)

    Es una función muy utilizada en el tratamiento de colecciones

    Función reduce

    Toma una función y una colección reduciéndola a un solo valor

    Sería equivalente a una función de agregación

    Pertenece al módulo functools, por lo que deberá ser importado antes de poder usar reduce

    La función que pasemos debe tomar al menos dos parámetros y uno opcional

    El primero es el parámetro del agregado que se va acumulado en cada iteración sobre los elementos de la colección

    El segundo el elemento corresponde al paso de la iteración

    El tercero es en caso que se necesite un valor inicial

Excepciones en Python

Excepciones en Python

Si una operación no puede completarse debido a un error, el programa deberá:

  • volver a un estado estable y permitir otras operaciones

  • intentar guardar el trabajo y finalizar

Esta tarea es difícil debido a que generalmente el código que detecta el error no es el que puede realizar dichas tareas por eso debe informar al que pueda manejarlo

La solución más habitual son los códigos de error

Python ofrece otra forma de tratar con los errores en condiciones excepcionales: las excepciones

Una condición excepcional es aquella que impide la continuación de una operación

No se sabe como manejarla, pero no se puede continuar

En Python se lanza una excepción para que alguien que sepa manejarla la trate en un contexto superior

En el ejemplo la función open comprueba si el fichero readme.txt existía en el sistema y en caso de no existir se lanza la excepción FileNotFoundError que de momento está sin tratar

Cuando el intérprete detecta el lanzamiento de la excepción finaliza el método actual y lanza un objeto que facilite información sobre el error ocurrido

Normalmente se gestionará cada tipo de error de forma individual

Manejo de la excepciones

Una vez detectado el error hace falta indicar quien se encarga de tratarlo

Un manejador de excepciones tiene el siguiente formato:

Bloque try

El bloque try delimita el grupo de operaciones que puede producir excepciones

Bloque except

El bloque except es el lugar al que se transfiere el control si alguna de las operaciones produce una excepción

En el ejemplo se ha usado un bloque try con su bloque except para gestionar los errores del ejemplo anterior

Si alguna de las operaciones del bloque produce una excepción, se interrumpe el bloque try y se ejecuta el except

Al finalizar este, se continua normalmente

Si no se produce ninguna excepción, el bloque except se ignora

Excepciones múltiples

También existe la posibilidad de utilizar un nombre de excepción para tratar errores específicos

Algunos de los cuales ya son reconocidos por el sistema, como la excepción FileNotFoundError, que se lanza cuando un archivo no existe en el sistema

En el ejemplo se ha usado un bloque try con varios bloques except para gestionar varias excepciones

Un bloque try puede tener varios except asociados

Le hemos añadimos la sentencia as al bloque except despues de nombrarlo para convertirlo en el objeto de excepción que hemos llamado e

Como puede verse, después de convertirlo en objeto, podemos utilizarlo como si fuera una clase

Cuando una excepción no se corresponde con ningún catch se propaga hacia atrás en la secuencia de invocaciones hasta encontrar un catch adecuado

En el ejemplo se gestionan las excepciones de los métodos f1 y f2 y si no encuentran ninguna continua la ejecución del código de forma normal fuera del bloque try

Se ha usado la sentencia raise seguida del nombre del tipo de excepción para propagarla y tratarla en otro lugar

En este caso la hemos tratado dentro de la propia función f1 en sus bloques excepción

Aunque al propagarla podría haberse tratado fuera de la misma en otro lugar del script

También se ha utilizado un bloque else que permite continuar la ejecución del código en caso de que no haya excepciones antes de continuar fuera del bloque try

Bloque else

Permite continuar la ejecución del código en caso de que no haya excepciones antes de continuar fuera del bloque try

El bloque else puede utilizarse para salir de un bucle si al final del mismo se añade la sentencia break

Es opcional y si no se usa, continuará la ejecución del código en el bloque finally y por último fuera del bloque try

Bloque finally

Puede haber ocasiones en que se desea realizar alguna operación tanto si se producen excepciones como si no

Dichas operaciones se pueden situar dentro de un bloque finally

Si no hay ninguna excepción se ejecutará el bloque try, después el bloque else y por último el finally

Al igual que el bloque else, es opcional y si no se usa, continuará la ejecución del código fuera del bloque try

Normas de uso

  1. Norma

    • Si una excepción se puede manejar no debe propagarse

    • Es más cómodo usar métodos que no produzcan errores

  2. Norma

    • No utilizar las excepciones para evitar una consulta

      • No abusar de ellas

  3. Norma

    • Separar el tratamiento de errores de la lógica

      Todo junto
      Separado
  4. Norma

    • No ignorar una excepción ya que dejamos el código con errores sin controlar