{ "cells": [ { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "# 6. Archivos & Manejo de excepciones\n", "--------------------------------------\n", "\n", "## Archivos\n", "\n", "Un archivo es información identificada con un nombre que puede ser almacenada de manera permanente en el directorio de un dispositivo. Hasta ahora, hemos estado leyendo y escribiendo en la entrada y salida estándar. Ahora, veremos cómo usar los archivos de datos reales.\n", "\n", "Python proporciona funciones y métodos básicos necesarios para manipular archivos de forma predeterminada. Puede realizar la mayor parte de la manipulación de archivos utilizando un objeto de archivo.\n", "\n", "\n", "### Función Open\n", "\n", "Antes de poder leer o escribir un archivo, debes abrirlo usando la función open () integrada de Python. Esta función crea un objeto de archivo, que se utilizará para llamar a otros métodos de soporte asociados con él.\n", "\n", "** Sintaxis **" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true, "deletable": true, "editable": true }, "outputs": [], "source": [ "file object = open(file_name [, access_mode])" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "Aquí están los detalles del parámetro:\n", "\n", "* **file_name:** El argumento **file_name** es una cadena que contiene el nombre del archivo al que desea acceder.\n", "\n", "* **access_mode:** El modo de acceso determina el modo en el que se debe abrir el archivo, es decir, leer(read), escribir(write), añadir(append), etc. A continuación se muestra una lista completa de valores posibles en la tabla. Este es un parámetro opcional y se lee el modo de acceso de archivo predeterminado (r)\n" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "Aquí hay una lista de los diferentes modos de abrir un archivo:" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true, "deletable": true, "editable": true }, "source": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", " \n", "\n", " \n", " \n", " \n", "\n", "
ModosDescripcion
rAbre un archivo sólo para lectura. El puntero del archivo se coloca al principio del archivo. Este es el modo por defecto.
rbAbre un archivo para la lectura sólo en formato binario. El puntero del archivo se coloca al principio del archivo. Este es el modo por defecto.
r+Abre un archivo para leer y escribir. El puntero de archivo colocado al principio del archivo.
rb+Abre un archivo para lectura y escritura en formato binario. El puntero de archivo colocado al principio del archivo.
wAbre un archivo para la escritura solamente. Sobrescribe el archivo si existe el archivo. Si el archivo no existe, crea un nuevo archivo para la escritura.
wbAbre un archivo para escribir sólo en formato binario. Sobrescribe el archivo si existe el archivo. Si el archivo no existe, crea un nuevo archivo para la escritura.
w+Abre un archivo para escribir y leer. Sobreescribe el archivo existente si existe el archivo. Si el archivo no existe, crea un nuevo archivo para leer y escribir.
wb+Abre un archivo para escribir y leer en formato binario. Sobreescribe el archivo existente si existe el archivo. Si el archivo no existe, crea un nuevo archivo para leer y escribir.
aAbre un archivo para agregar. El puntero de archivo está al final del archivo si existe el archivo. Es decir, el archivo está en el modo de agregación. Si el archivo no existe, crea un nuevo archivo para la escritura.
abAbre un archivo para anexar en formato binario. El puntero de archivo está al final del archivo si existe el archivo. Es decir, el archivo está en el modo de agregación. Si el archivo no existe, crea un nuevo archivo para la escritura.
a+Abre un archivo para agregar y leer. El puntero de archivo está al final del archivo si existe el archivo. El archivo se abre en el modo de agregación. Si el archivo no existe, crea un nuevo archivo para leer y escribir.
ab+Abre un archivo para agregar y leer en formato binario. El puntero de archivo está al final del archivo si existe el archivo. El archivo se abre en el modo de agregación. Si el archivo no existe, crea un nuevo archivo para leer y escribir.
" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true, "deletable": true, "editable": true }, "source": [ "### Los atributos del objeto File\n" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true, "deletable": true, "editable": true }, "source": [ "Una vez que se abre un archivo y tiene un objeto de archivo, puede obtener información relacionada con ese archivo. \n", "\n", "Aquí hay una lista de todos los atributos relacionados con el objeto file:" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true, "deletable": true, "editable": true }, "source": [ "\n", "\n", "\n", "\n", "\n", "
AtributoDescripción
file.closedDevuelve true si el archivo está cerrado, false de lo contrario.
file.modeDevuelve el modo de acceso con el que se abrió el archivo.
file.nameDevuelve el nombre del archivo.
\n" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true, "deletable": true, "editable": true }, "source": [ "Ahora veamos un ejemplo:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": true, "deletable": true, "editable": true }, "outputs": [], "source": [ "fo = open(\"foo.txt\", \"wb\")" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Name of the file: foo.txt\n", "Closed or not : False\n", "Opening mode : wb\n" ] } ], "source": [ "print (\"Name of the file: \", fo.name)\n", "print (\"Closed or not : \", fo.closed)\n", "print (\"Opening mode : \", fo.mode)\n", "fo.close() # Método close() OJO METODO NO ATRIBUTO!! NO CONFUNDIR con .closed (atributo)" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true, "deletable": true, "editable": true }, "source": [ "### Método close()\n", "El método **close()** de un objeto de archivo vacía cualquier información no escrita y cierra el objeto de archivo, después de lo cual no se puede realizar más escritura.\n", "\n", "Python cierra automáticamente un archivo cuando el objeto de referencia de un archivo se reasigna a otro archivo. Es una buena práctica utilizar el método close () para cerrar un archivo." ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "### Leyendo y Escribiendo Archivos\n", "\n", "El objeto **file** proporciona un conjunto de métodos de acceso para facilitar nuestras vidas. Veremos cómo usar los métodos **read()** y **write()** para leer y escribir archivos.\n", "\n", "### Método write()\n", "El método **write()** escribe cualquier cadena en un archivo abierto. Es importante tener en cuenta que las cadenas de Python pueden tener datos binarios y no sólo texto.\n", "\n", "El método write () no agrega un carácter de nueva línea **('\\ n')** al final de la cadena" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [], "source": [ "# Copien esto en script, luego de ejecutar se creará un archivo llamado foo1.txt, abránlo y vean la magia ;) \n", "# Para escribir multiples lineas usen \"\"\"(triples comillas)\"\"\"\n", "\n", "# Abriendo un archivo\n", "fo = open(\"foo1.txt\", \"w\")\n", "fo.write(\"\"\"Los ordenadores son increíblemente rápidos, precisos, y estúpidos \\n\n", "Los humanos son increíblemente lentos, imprecisos, y brillantes. \\n\n", "Juntos, su potencia está más allá de lo imaginable. \"\"\")\n", "# Cerrando el archivo abierto\n", "fo.close()" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "El método anterior creará el archivo foo.txt y escribirá el contenido dado en ese archivo y finalmente cerrará ese archivo. Si usted abriría este archivo, abŕalo y vea el resultado." ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "### Método read()\n", "\n", "El método **read()** lee una cadena de un archivo abierto. Es importante tener en cuenta que las cadenas de Python pueden tener datos binarios. Aparte de los datos de texto.\n", "\n", "En el método read() el parámetro pasado es el número de bytes que se leerán del archivo abierto. Este método comienza a leer desde el principio del archivo y si falta la cuenta, entonces intenta leer tanto como sea posible, tal vez hasta el final del archivo." ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "La cadena leida es : Los ordenadores son \n", "----------------------------------\n", "increíblemente rápidos, precisos, y estúpidos \n", "\n", "Los humanos son increíblemente lentos, imprecisos, y brillantes. \n", "\n", "Juntos, su potencia está más allá de lo imaginable. \n" ] } ], "source": [ "# Abriendo el archivo foo1\n", "fo = open(\"foo1.txt\", \"r+\")\n", "\n", "# Le pasamos como argumentos 20 bytes\n", "str = fo.read(20)\n", "print (\"La cadena leida es : \", str)\n", "\n", "print(\"----------------------------------\")\n", "\n", "# Cuando hagamos nuevamente foo.read() leerá los siguientes carácteres despues de haber leido lo demás\n", "print (fo.read())\n", "# Cerrando el archivo abierto\n", "fo.close()" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "### Posición de un archivo\n", "\n", "El método **tell()** le indica la posición actual dentro del archivo; En otras palabras, la próxima lectura o escritura se producirá en la posición que este metodo nos indique.\n", "\n", "El método **seek(offset [, from])** cambia la posición del archivo actual. El argumento offset indica el número de bytes que se deben mover. El argumento from especifica la posición de referencia desde donde se deben mover los bytes.\n", "\n", "Si from está puesto a 0, significa usar el comienzo del archivo como la posición de referencia y 1 significa usar la posición actual como la posición de referencia y si se establece en 2 entonces el final del archivo se tomaría como la posición de referencia ." ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false, "deletable": true, "editable": true, "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "La cadena leida es: Los ordenadores\n", "Posición actual del archivo : 15\n", "Una vez más, la cadena de lectura es: Los ordenadores\n" ] } ], "source": [ "# Abriendo un archivo\n", "fo = open(\"foo1.txt\", \"r+\")\n", "str = fo.read(15)\n", "print (\"La cadena leida es: \", str)\n", "\n", "# Checkea la posicion actual\n", "position = fo.tell()\n", "print (\"Posición actual del archivo : \", position)\n", "\n", "# Vuelva a colocar el puntero al principio una vez más\n", "position = fo.seek(0, 0)\n", "str = fo.read(15)\n", "print (\"Una vez más, la cadena de lectura es: \", str)\n", "# Cerrando el achivo abierto\n", "fo.close()" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "### Ahora veamos un ejemplo del uso de archivos" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1. Imprimir los nueros de teléfono\n", "2. Añade un numero de teléfono\n", "3. Elimina un numero de teléfono\n", "4. Busca un numero de teléfono\n", "5. Carga numeros\n", "6. Guarda numeros\n", "7. Salir\n", "\n", "Ingrese un numero del (1-7): 1\n", "Numeros de Telefono:\n", "\n", "Ingrese un numero del (1-7): 5\n", "Archivo a cargar: numeros.txt\n", "Ingrese un numero del (1-7): 1\n", "Numeros de Telefono:\n", "nombre: Carla \t Numero: 912312121\n", "nombre: Maria \t Numero: 989123876\n", "\n", "Ingrese un numero del (1-7): 2\n", "Ingrese un nombre y un numero\n", "Nombre: Megumi\n", "Numero: 908321786\n", "Ingrese un numero del (1-7): 1\n", "Numeros de Telefono:\n", "nombre: Carla \t Numero: 912312121\n", "nombre: Maria \t Numero: 989123876\n", "nombre: Megumi \t Numero: 908321786\n", "\n", "Ingrese un numero del (1-7): 2\n", "Ingrese un nombre y un numero\n", "Nombre: Kosaki\n", "Numero: 908123867\n", "Ingrese un numero del (1-7): 3\n", "Remover el nombre y numero\n", "Ingrese el nombre que desee eliminar: Carla\n", "Ingrese un numero del (1-7): 1\n", "Numeros de Telefono:\n", "nombre: Maria \t Numero: 989123876\n", "nombre: Megumi \t Numero: 908321786\n", "nombre: Kosaki \t Numero: 908123867\n", "\n", "Ingrese un numero del (1-7): 4\n", "Busque un numero\n", "Nombre: Kosaki\n", "El numero es 908123867\n", "Ingrese un numero del (1-7): 6\n", "Archivo a guardar: numeros2.txt\n", "Ingrese un numero del (1-7): 7\n", "Adios :c \n" ] } ], "source": [ "# Este programa es una agenda telefónica\n", "\n", "# Imprime los nombres y sus respectivos números\n", "def print_numbers(numbers):\n", " print(\"Numeros de Telefono:\")\n", " for k, v in numbers.items():\n", " print(\"nombre:\", k, \"\\t Numero:\", v)\n", " print()\n", "\n", "# Añande un numero\n", "def add_number(numbers, name, number):\n", " numbers[name] = number\n", "\n", "# Verifica si un numero se encuentra o no en la agenda\n", "def lookup_number(numbers, name):\n", " if name in numbers:\n", " return \"El numero es \" + numbers[name]\n", " else:\n", " return name + \" no ha sido encontrado\"\n", "\n", "# Elimina un número\n", "def remove_number(numbers, name):\n", " if name in numbers:\n", " del numbers[name]\n", " else:\n", " print(name,\" no ha sido encontrado\")\n", "\n", "# Carga números\n", "def load_numbers(numbers, filename):\n", " in_file = open(filename, \"rt\")\n", " while True:\n", " in_line = in_file.readline()\n", " if not in_line:\n", " break\n", " in_line = in_line[:-1]\n", " name, number = in_line.split(\",\")\n", " numbers[name] = number\n", " in_file.close()\n", "\n", "# Guarda numeros\n", "def save_numbers(numbers, filename):\n", " out_file = open(filename, \"wt\")\n", " for k, v in numbers.items():\n", " out_file.write(k + \",\" + v + \"\\n\")\n", " out_file.close()\n", "\n", "# Menu de inicio\n", "def print_menu():\n", " print('1. Imprimir los nueros de teléfono')\n", " print('2. Añade un numero de teléfono')\n", " print('3. Elimina un numero de teléfono')\n", " print('4. Busca un numero de teléfono')\n", " print('5. Carga numeros')\n", " print('6. Guarda numeros')\n", " print('7. Salir')\n", " print()\n", "\n", "# Crea un diccionario vacio\n", "phone_list = {}\n", "\n", "# Inicializa la decicion como 0\n", "menu_choice = 0\n", "\n", "# Inicia el programa\n", "print_menu()\n", "\n", "while True:\n", " menu_choice = int(input(\"Ingrese un numero del (1-7): \"))\n", " if menu_choice == 1:\n", " print_numbers(phone_list)\n", " elif menu_choice == 2:\n", " print(\"Ingrese un nombre y un numero\")\n", " name = input(\"Nombre: \")\n", " phone = input(\"Numero: \")\n", " add_number(phone_list, name, phone)\n", " elif menu_choice == 3:\n", " print(\"Remover el nombre y numero\")\n", " name = input(\"Ingrese el nombre que desee eliminar: \")\n", " remove_number(phone_list, name)\n", " elif menu_choice == 4:\n", " print(\"Busque un numero\")\n", " name = input(\"Nombre: \")\n", " print(lookup_number(phone_list, name))\n", " elif menu_choice == 5:\n", " filename = input(\"Archivo a cargar: \")\n", " load_numbers(phone_list, filename)\n", " elif menu_choice == 6:\n", " filename = input(\"Archivo a guardar: \")\n", " save_numbers(phone_list, filename)\n", " elif menu_choice == 7:\n", " break\n", " else:\n", " print_menu()\n", "\n", "print(\"Adios :c \")" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "Ahora abran el archivo numeros2.txt y vean la magia :O " ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "## Errores\n", "\n", "En un programa podemos encontrarnos con distintos tipos de errores pero a grandes rasgos podemos decir que todos los errores pertenecen a una de las siguientes categorías.\n", "\n", "- **Errores de sintaxis:** estos errores son seguramente los más simples de resolver, pues son detectados por el intérprete (o por el compilador, según el tipo de lenguaje que estemos utilizando) al procesar el código fuente y generalmente son consecuencia de equivocaciones al escribir el programa. En el caso de Python estos errores son indicados con un mensaje SyntaxError. Por ejemplo, si trabajando con Python intentamos definir una función y en lugar de def escribimos dev.\n", "\n", "- **Errores semánticos:** se dan cuando un programa, a pesar de no generar mensajes de error, no produce el resultado esperado. Esto puede deberse, por ejemplo, a un algoritmo incorrecto o a la omisión de una sentencia.\n", "\n", "- **Errores de ejecución:** estos errores aparecen durante la ejecución del programa y su origen puede ser diverso. En ocasiones pueden producirse por un uso incorrecto del programa por parte del usuario, por ejemplo si el usuario ingresa una cadena cuando se espera un número. En otras ocasiones pueden deberse a errores de programación, por ejemplo si una función intenta acceder a la quinta posición de una lista de 3 elementos o realizar una división por cero. Una causa común de errores de ejecución que generalmente excede al programador y al usuario, son los recursos externos al programa, por ejemplo si el programa intenta leer un archivo y el mismo se encuentra dañado.\n", "\n", "Tanto a los errores de sintaxis como a los semánticos se los puede detectar y corregir durante la construcción del programa ayudados por el intérprete y la ejecución de pruebas. Pero no ocurre esto con los errores de ejecución ya que no siempre es posible saber cuando ocurrirán y puede resultar muy complejo (o incluso casi imposible) reproducirlos. Es por ello que el resto de la unidad nos centraremos en cómo preparar nuestros programas para lidiar con este tipo de errores." ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "### Excepciones\n", "\n", "Los errores de ejecución son llamados comúnmente excepciones y por eso de ahora en más utilizaremos ese nombre. Durante la ejecución de un programa, si dentro de una función surge una excepción y la función no la maneja, la excepción se propaga hacia la función que la invocó, si esta otra tampoco la maneja, la excepción continua propagándose hasta llegar a la función inicial del programa y si esta tampoco la maneja se interrumpe la ejecución del programa. Veamos entonces como manejar excepciones.\n", "\n", "#### Manejo de excepciones\n", "\n", "Para el manejo de excepciones los lenguajes proveen ciertas palabras reservadas, que nos permiten manejar las excepciones que puedan surgir y tomar acciones de recuperación para evitar la interrupción del programa o, al menos, para realizar algunas acciones adicionales antes de interrumpir el programa.\n", "\n", "En el caso de Python, el manejo de excepciones se hace mediante los bloques que utilizan las sentencias **try**, **except** y **finally**.\n", "\n", "Dentro del bloque try se ubica todo el código que pueda llegar a levantar una excepción, se utiliza el término levantar para referirse a la acción de generar una excepción.\n", "\n", "A continuación se ubica el bloque except, que se encarga de capturar la excepción y nos da la oportunidad de procesarla mostrando por ejemplo un mensaje adecuado al usuario. Veamos qué sucede si se quiere realizar una división por cero:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "ename": "ZeroDivisionError", "evalue": "division by zero", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mZeroDivisionError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mdividendo\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m8\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0mdivisor\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mcociente\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdividendo\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0mdivisor\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mZeroDivisionError\u001b[0m: division by zero" ] } ], "source": [ "dividendo = 8\n", "divisor = 0\n", "cociente = dividendo / divisor" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "En este caso, se levantó la excepción **ZeroDivisionError** cuando se quiso hacer la división. Para evitar que se levante la excepción y se detenga la ejecución del programa, se utiliza el bloque **try-except**." ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "No se pudo efectuar la division\n" ] } ], "source": [ "try:\n", " cociente = dividendo / divisor\n", "except:\n", " print(\"No se pudo efectuar la division\")" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "Tambíen podemos capturar multiples excepciones mediante la estrcutura:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true, "deletable": true, "editable": true }, "outputs": [], "source": [ "try:\n", " # aquí ponemos el código que puede lanzar excepciones\n", "except IOError:\n", " # entrará aquí en caso que se haya producido una excepción IOError\n", "except ZeroDivisionError:\n", " # entrará aquí en caso que se haya producido una excepción ZeroDivisionError\n", "except: \n", " # entrará aquí en caso que se haya producido una excepción que no corresponda a ninguno\n", " # de los tipos especificados en los except previos" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Ingrese un número: 0\n", "Pero que el número no sea cero!\n", "Ingrese un número: 5\n", "12 / 5 = 2.4\n" ] } ], "source": [ "while True:\n", " try:\n", " num_str = input('Ingrese un número: ')\n", " num = int(num_str)\n", " print(\"{} / {} = {}\".format(12,num, 12/num ))\n", " break\n", " except ValueError:\n", " print('Ingresa un número válido')\n", " except ZeroDivisionError:\n", " print('Pero que el número no sea cero!')" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "Finalmente, puede ubicarse un bloque **finally** donde se escriben las sentencias de finalización, que son típicamente acciones de limpieza. La particularidad del bloque finally es que se ejecuta siempre, haya surgido una excepción o no. Si hay un bloque except, no es necesario que esté presente el finally, y es posible tener un bloque try sólo con finally, sin except." ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "No pude convertir el dato a un entero.\n", "Ha terminado el bloque\n" ] } ], "source": [ "import sys\n", "\n", "try:\n", " f = open('miarchivo.txt')\n", " s = f.readline()\n", " i = int(s.strip())\n", "except OSError as err:\n", " print(\"Error OS: {0}\".format(err))\n", "except ValueError:\n", " print(\"No pude convertir el dato a un entero.\")\n", "except:\n", " print(\"Error inesperado:\", sys.exc_info()[0])\n", "finally:\n", " print(\"Ha terminado el bloque\")" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "### Levantando excepciones" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "La declaración **raise** permite al programador forzar a que ocurra una excepción específica. Por ejemplo:" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "ename": "NameError", "evalue": "How you doing?", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mNameError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'How you doing?'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mNameError\u001b[0m: How you doing?" ] } ], "source": [ "raise NameError('How you doing?')" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "El único argumento a raise indica la excepción a generarse. Tiene que ser o una instancia de excepción, o una clase de excepción (una clase que hereda de Exception).\n", "\n", "Si necesitás determinar cuando una excepción fue lanzada pero no querés manejarla, una forma simplificada de la instrucción raise te permite relanzarla:" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Acaba de ocurrir una excepción!\n" ] }, { "ename": "NameError", "evalue": "I am fine", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mNameError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'I am fine'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mNameError\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Acaba de ocurrir una excepción!'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;32mraise\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mNameError\u001b[0m: I am fine" ] } ], "source": [ "try:\n", " raise NameError('I am fine')\n", "except NameError:\n", " print('Acaba de ocurrir una excepción!')\n", " raise" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "De más está decir, que las excepciones pueden ser personalizadas según sea necesario:" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Error creado: Archivos inválidos ('a.conf', 'b.conf')\n" ] } ], "source": [ "class MiError(Exception):\n", " \n", " def __init__(self, mssg, ref=''):\n", " self.mssg = mssg\n", " self.ref = ref\n", " \n", " def __str__(self,):\n", " return \"Error creado: {} {}\".format(self.mssg, self.ref)\n", " \n", "try:\n", " raise MiError(\"Archivos inválidos\", ('a.conf','b.conf') )\n", "except MiError as e:\n", " print(e)" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/html": [ "/* This template is inspired in the one used by Lorena Barba\n", "in the numerical-mooc repository: https://github.com/numerical-mooc/numerical-mooc\n", "We thank her work and hope you also enjoy the look of the notobooks with this style */\n", "\n", "\n", "Estilo aplicado\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Esta celda da el estilo al notebook\n", "from IPython.core.display import HTML\n", "css_file = '../styles/StyleCursoPython.css'\n", "HTML(open(css_file, \"r\").read())" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.0" } }, "nbformat": 4, "nbformat_minor": 1 }