Básico sobre tratamento de exceções em Python 3.4

Resolvi fazer um básico sobre Python, que ainda não domino completamente, mas de todas as linguagens que já vi, foi a que eu mais gostei, pois une poder a simplicidade.

[ Hits: 11.906 ]

Por: Perfil removido em 26/02/2015


Introdução



Resolvi fazer um básico sobre Python, que ainda não domino completamente, mas de todas as linguagens que já vi, foi a que eu mais gostei, pois une poder a simplicidade.

Bom, vamos lá então.

O que é o tratamento de exceções?

Sem copiar textos de outros lugares, para entender o tratamento de exceções, precisamos entender o que é uma exceção dentro da programação.
Linux: Básico sobre tratamento de exceções em Python 3.4
Uma exceção é algo que saía fora do planejado, por exemplo, você querer somar dois números, mas acabar inserindo uma letra e um número, irá gerar um erro, esse erro é a chamada exceção. Exceções muitas vezes são feias, visualmente falando, e acabam trazendo informações desnecessárias ao usuário final e algumas vezes causam até o vazamento de informações.

O tratamento de exceções é basicamente filtrar esses erros "feios", que costumam apresentar informações mais técnicas, para ajudar o programador a encontrar o erro, e exibir somente uma mensagem mais amigável e talvez com apenas um código do erro.

Na prática...

Um script simples para somar 2 números:

python
>>> N1 = 25
>>> N2 = 'asd'
>>> N1 + N2
Traceback (most recent call last):
  File "<pyshell#5>", line 1, in <module>
    N1 + N2
TypeError: unsupported operand type(s) for +: 'int' and 'str'


Essa:

Traceback (most recent call last):
  File "<pyshell#5>", line 1, in <module>
    N1 + N2
TypeError: unsupported operand type(s) for +: 'int' and 'str'


É a exceção, que informa ali a linha onde ocorreu o erro e o tipo, isso é feio para o usuário e na maioria das vezes só vai confundi-lo, então vamos usar o chamado tratamento de exceções. Em Python, assim como em muitas linguagens, ele é feito na sua forma mais básica com try e except.

Sua sintaxe é semelhante a muitas linguagens de alto de nível:

try:
   comandos
except:
   comandos que deverão ser executados caso de algo errado

Voltando a código ali de cima, vamos filtrar esse erro:

>>> N1 = 25
>>> N2 = 'asd'
>>> try:
    N1 + N2
except:
    print('erro ao tentar realizar a soma')


Executando:

erro ao tentar realizar a soma
>>>

E já filtramos o erro, porém isso é muito vago, por que ocorreu o erro?

Para resolver isso, podemos criar exceções específicas para cada tipo de erro. O Python é bem gentil nessa parte e já te diz direto o tipo de erro. Voltando lá em cima no erro, qual o tipo de erro?

Traceback (most recent call last):
  File "<pyshell#5>", line 1, in <module>
    N1 + N2
TypeError: unsupported operand type(s) for +: 'int' and 'str'


TypeError! Então aí já sabemos o tipo do erro e podemos criar uma exceção específica pra erros desse tipo:

>>> N1 = 25
>>> N2 = 'asd'
>>> try:
    N1 + N2
except TypeError:
    print('erro ao tentar realizar a soma, tipos de dados diferentes')


Executando:

erro ao tentar realizar a soma, tipos de dados diferentes
>>>

À primeira vista, parece ser a mesma coisa, usar except somente e except <tipo do erro>, mas para códigos maiores, onde existam possibilidades de tipos diferentes de erros, isso ajuda tanto o programador, quanto o usuário a terem uma ideia do que saiu errado.

Um exemplo genérico: dois erros comuns ao se trabalhar com urllib, um erro HTTP e um erro na URL:

>>> url.urlopen('http://www.sitenaoexiste.com')
Traceback (most recent call last):
  File "C:\Python34\lib\urllib\request.py", line 1174, in do_open
    h.request(req.get_method(), req.selector, req.data, headers)
  File "C:\Python34\lib\http\client.py", line 1090, in request
    self._send_request(method, url, body, headers)
  File "C:\Python34\lib\http\client.py", line 1128, in _send_request
    self.endheaders(body)
  File "C:\Python34\lib\http\client.py", line 1086, in endheaders
    self._send_output(message_body)
  File "C:\Python34\lib\http\client.py", line 924, in _send_output
    self.send(msg)
  File "C:\Python34\lib\http\client.py", line 859, in send
    self.connect()
  File "C:\Python34\lib\http\client.py", line 836, in connect
    self.timeout, self.source_address)
  File "C:\Python34\lib\socket.py", line 491, in create_connection
    for res in getaddrinfo(host, port, 0, SOCK_STREAM):
  File "C:\Python34\lib\socket.py", line 530, in getaddrinfo
    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno 11004] getaddrinfo failed

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<pyshell#61>", line 1, in <module>
    url.urlopen('http://www.sitenaoexiste.com')
  File "C:\Python34\lib\urllib\request.py", line 153, in urlopen
    return opener.open(url, data, timeout)
  File "C:\Python34\lib\urllib\request.py", line 455, in open
    response = self._open(req, data)
  File "C:\Python34\lib\urllib\request.py", line 473, in _open
    '_open', req)
  File "C:\Python34\lib\urllib\request.py", line 433, in _call_chain
    result = func(*args)
  File "C:\Python34\lib\urllib\request.py", line 1202, in http_open
    return self.do_open(http.client.HTTPConnection, req)
  File "C:\Python34\lib\urllib\request.py", line 1176, in do_open
    raise URLError(err)
urllib.error.URLError: <urlopen error [Errno 11004] getaddrinfo failed>



>>> url.urlopen('http://www.webcheats.com.br')
Traceback (most recent call last):
  File "<pyshell#62>", line 1, in <module>
    url.urlopen('http://www.webcheats.com.br')
  File "C:\Python34\lib\urllib\request.py", line 153, in urlopen
    return opener.open(url, data, timeout)
  File "C:\Python34\lib\urllib\request.py", line 461, in open
    response = meth(req, response)
  File "C:\Python34\lib\urllib\request.py", line 571, in http_response
    'http', request, response, code, msg, hdrs)
  File "C:\Python34\lib\urllib\request.py", line 499, in error
    return self._call_chain(*args)
  File "C:\Python34\lib\urllib\request.py", line 433, in _call_chain
    result = func(*args)
  File "C:\Python34\lib\urllib\request.py", line 579, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 403: Forbidden

>>>

O primeiro erro é porque o site não existe, o segundo é porque o fórum bloqueia certas requisições, até onde eu vi, com base no user-agent, pois alterando o user-agent da minha requisição, consegui conectar (mas isso é assunto pra outra hora).

Se tentássemos usar o try, não saberíamos ao certo o que deu errado.

>>> try:
    url.urlopen('http://www.sitenaoexiste.com')
except:
    print('erro')

erro

>>> try:
    url.urlopen('http://www.webcheats.com.br')
except:
    print('erro')

erro
>>>

Já se tentarmos filtrar por tipo de erro:

>>> try:
    url.urlopen('http://www.sitenaoexiste.com')
except urllib.error.HTTPError:
    print('Erro HTTP')
except urllib.error.URLError:
    print('erro ao tentar abrir a URL')


erro ao tentar abrir a URL

>>> try:
    url.urlopen('http://www.webcheats.com.br')
except urllib.error.HTTPError:
    print('Erro HTTP')
except urllib.error.URLError:
    print('erro ao tentar abrir a URL')


Erro HTTP
>>>

Mas podemos dar ainda mais detalhes sobre o erro, de forma amigável, pegando o erro HTTP por exemplo, existem vários tipos: error 404, 403 etc, que são códigos que servem para dizer o que deu errado. Para quem quiser dar uma olhada nos códigos:
>>> try:
    url.urlopen('http://www.webcheats.com.br')
except urllib.error.HTTPError as errohttp:
    print('Erro HTTP, código do erro: {code}' .format(code = errohttp.code))
except urllib.error.URLError:
    print('erro ao tentar abrir a URL')


Erro HTTP, código do erro: 403
>>>

E é isso aí. :)

Fonte:
   

Páginas do artigo
   1. Introdução
Outros artigos deste autor

Instalando programas utilizando os fontes no seu Slackware com o checkinstall

Como fazer seu programa Kylix chamar uma aplicação externa

Por que existem mais games para Windows do que para Linux?

Prevenindo problemas com impressoras via Samba no Windows

Configurando firewall básico para compartilhar internet

Leitura recomendada

Asterisk - O sistema de telefonia open source

Lucaschess: software para base de dados, jogar e treinar xadrez

Vida nova para o Kurumin 7

Instalando seu Debian Sarge (Parte I)

Repositórios, pacotes, o que são?

  
Comentários
[1] Comentário enviado por hrcerq em 27/02/2015 - 09:59h

Excelente artigo! Parabéns.

[2] Comentário enviado por malbrecht em 28/02/2015 - 08:48h

Muito bom artigo, Parabéns

[3] Comentário enviado por gilsonsilvati em 28/02/2015 - 17:07h

Show... Parabéns pelo tutorial!!! :-)

[4] Comentário enviado por bonilhasilvio em 07/03/2015 - 13:04h


Valeu, muito bom tutorial.


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner
Linux banner
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts