{ "metadata": { "name": "Capitulo13_Excecoes" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "[Python para Desenvolvedores](http://ricardoduarte.github.io/python-para-desenvolvedores/#conteudo)\n", "===================================\n", "2ª edi\u00e7\u00e3o, revisada e ampliada\n", "-----------------------------------\n", "\n", "Cap\u00edtulo 13: Exce\u00e7\u00f5es\n", "=============================\n", "_____________________________\n", "Quando ocorre uma falha no programa (como uma divis\u00e3o por zero, por exemplo) em tempo de execu\u00e7\u00e3o, uma exce\u00e7\u00e3o \u00e9 gerada. Se a exce\u00e7\u00e3o n\u00e3o for tratada, ela ser\u00e1 propagada atrav\u00e9s das chamadas de fun\u00e7\u00e3o at\u00e9 o m\u00f3dulo principal do programa, interrompendo a execu\u00e7\u00e3o." ] }, { "cell_type": "code", "collapsed": false, "input": [ "print 1/0" ], "language": "python", "metadata": {}, "outputs": [ { "ename": "ZeroDivisionError", "evalue": "integer division or modulo by zero", "output_type": "pyerr", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mZeroDivisionError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[1;32mprint\u001b[0m \u001b[1;36m1\u001b[0m\u001b[1;33m/\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[1;31mZeroDivisionError\u001b[0m: integer division or modulo by zero" ] } ], "prompt_number": 1 }, { "cell_type": "markdown", "metadata": {}, "source": [ "A instru\u00e7\u00e3o *try* permite o tratamento de exce\u00e7\u00f5es no Python. Se ocorrer uma exce\u00e7\u00e3o em um bloco marcado com *try*, \u00e9 poss\u00edvel tratar a exce\u00e7\u00e3o atrav\u00e9s da instru\u00e7\u00e3o *except*. Podem existir v\u00e1rios blocos *except* para o mesmo bloco *try*." ] }, { "cell_type": "code", "collapsed": false, "input": [ "try:\n", " print 1/0\n", "except ZeroDivisionError:\n", " print 'Erro ao tentar dividir por zero.'" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Erro ao tentar dividir por zero.\n" ] } ], "prompt_number": 2 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Se *except* recebe o nome da exce\u00e7\u00e3o, s\u00f3 esta ser\u00e1 tratada. Se n\u00e3o for passada nenhuma exce\u00e7\u00e3o como par\u00e2metro, todas ser\u00e3o tratadas.\n", "\n", "Exemplo:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "import traceback\n", "\n", "# Tente receber o nome do arquivo\n", "try:\n", " fn = raw_input('Nome do arquivo: ').strip()\n", "\n", " # Numerando as linhas\n", " for i, s in enumerate(file(fn)):\n", " print i + 1, s,\n", "\n", "# Se ocorrer um erro\n", "except:\n", "\n", " # Mostre na tela\n", " trace = traceback.format_exc()\n", "\n", " # E salve num arquivo\n", " print 'Aconteceu um erro:\\n', trace\n", " file('trace.log', 'a').write(trace)\n", "\n", " # Encerre o programa\n", " raise SystemExit" ], "language": "python", "metadata": {}, "outputs": [ { "ename": "SystemExit", "evalue": "", "output_type": "pyerr", "traceback": [ "An exception has occurred, use %tb to see the full traceback.\n", "\u001b[1;31mSystemExit\u001b[0m\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "Aconteceu um erro:\n", "Traceback (most recent call last):\n", " File \"\", line 5, in \n", " fn = raw_input('Nome do arquivo: ').strip()\n", " File \"/usr/local/lib/python2.7/dist-packages/IPython/zmq/ipkernel.py\", line 345, in \n", " raw_input = lambda prompt='' : self._no_raw_input()\n", " File \"/usr/local/lib/python2.7/dist-packages/IPython/zmq/ipkernel.py\", line 688, in _no_raw_input\n", " raise StdinNotImplementedError(\"raw_input was called, but this \"\n", "StdinNotImplementedError: raw_input was called, but this frontend does not support stdin.\n", "\n" ] }, { "output_type": "stream", "stream": "stderr", "text": [ "To exit: use 'exit', 'quit', or Ctrl-D." ] } ], "prompt_number": 3 }, { "cell_type": "markdown", "metadata": {}, "source": [ "O m\u00f3dulo *traceback* oferece fun\u00e7\u00f5es para manipular as mensagens de erro. A fun\u00e7\u00e3o format_exc() retorna a sa\u00edda da \u00faltima exce\u00e7\u00e3o formatada em uma *string*.\n", "\n", "O tratamento de exce\u00e7\u00f5es pode possuir um bloco *else*, que ser\u00e1 executado quando n\u00e3o ocorrer nenhuma exce\u00e7\u00e3o e um bloco *finally*, ser\u00e1 executado de qualquer forma, tendo ocorrido uma exce\u00e7\u00e3o ou n\u00e3o. Novos tipos de exce\u00e7\u00f5es podem ser definidos atrav\u00e9s de heran\u00e7a a partir da classe *Exception*.\n", "\n", "A partir da vers\u00e3o 2.6, est\u00e1 dispon\u00edvel a instru\u00e7\u00e3o *with*, que pode substituir a combina\u00e7\u00e3o *try / finally* em v\u00e1rias situa\u00e7\u00f5es. Com *with*, podemos definir um objeto que ser\u00e1 usado durante a execu\u00e7\u00e3o do bloco. O objeto precisa suportar o protocolo de gerenciamento de contexto, o que significa que ele deve possuir um m\u00e9todo `__enter__()`, que \u00e9 executado no inicio do bloco, e outro chamado `__exit__()`, que \u00e9 evocado ao final do bloco.\n", "\n", "Exemplo:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "import random\n", "\n", "# Cria um arquivo com 25 n\u00fameros rand\u00f4micos\n", "with file('temp.txt', 'w') as temp:\n", " for y in range(5):\n", " for x in range(5):\n", " # \"print >> \" grava a sa\u00edda do comando no arquivo indicado\n", " print >> temp, '%.2f' % random.random(),\n", " print >> temp\n", "\n", "# Exibe o conte\u00fado do arquivo\n", "with file('temp.txt') as temp:\n", " for i in temp:\n", " print i,\n", "\n", "# Fora dos blocos, o arquivo est\u00e1 fechado\n", "# Isso gera uma exce\u00e7\u00e3o ValueError: I/O operation on closed file\n", "print >> temp" ], "language": "python", "metadata": {}, "outputs": [ { "ename": "ValueError", "evalue": "I/O operation on closed file", "output_type": "pyerr", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mValueError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 16\u001b[0m \u001b[1;31m# Fora dos blocos, o arquivo est\u00e1 fechado\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 17\u001b[0m \u001b[1;31m# Isso gera uma exce\u00e7\u00e3o ValueError: I/O operation on closed file\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 18\u001b[1;33m \u001b[1;32mprint\u001b[0m \u001b[1;33m>>\u001b[0m \u001b[0mtemp\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[1;31mValueError\u001b[0m: I/O operation on closed file" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "0.92 0.67 0.35 0.06 0.12\n", "0.30 0.57 0.29 0.90 0.94\n", "0.51 0.54 0.57 0.58 0.52\n", "0.55 0.00 0.19 0.23 0.50\n", "1.00 0.26 0.66 0.43 0.56\n" ] } ], "prompt_number": 4 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Como o arquivo foi fechado ao final do bloco, a tentativa de grava\u00e7\u00e3o gera uma exce\u00e7\u00e3o." ] }, { "cell_type": "code", "collapsed": false, "input": [], "language": "python", "metadata": {}, "outputs": [ { "html": [ "\n", "" ], "output_type": "pyout", "prompt_number": 1, "text": [ "" ] } ], "prompt_number": 1 } ], "metadata": {} } ] }