Sei sulla pagina 1di 23

Claudio Esperana

Python:
Python:
Excees, Iteradores e Geradores
Excees, Iteradores e Geradores
Excees
Excees

Quando um programa encontra dificuldades no


previstas, diz-se que uma condio excepcional ou uma
exceo ocorreu

Um erro uma exceo mas nem toda exceo um erro

Para poder representar tais eventos, Python define os


chamados objetos de exceo (exception objects)

Se a condio excepcional no prevista (e tratada), o


programa termina com uma mensagem de rastreamento:
>>> 1/0
Traceback (most recent call last):
File "<pyshell#0>", line 1, in -topleel-
1/0
!ero"iision#rror: inte$er %iision or mo%&lo by
'ero
Objetos de Exceo
Objetos de Exceo

Cada exceo individual corresponde a um objeto de


exceo, que por sua vez uma instncia de alguma classe
de exceo

No exemplo anterior, tal objeto instncia da classe


ZeroDivisionError

Diz-se que o programa gerou ou levantou (raised, em


ingls) uma condio de exceo na forma de um objeto

Um programa bem elaborado precisa capturar (catch, em


ingls) tais objetos e trat-los para que a execuo no seja
abortada
Avisos
Avisos

Existem condies excepcionais menos srias que no


provocam o levantamento de um objeto de exceo, mas apenas
so exibidas sob a forma de um aviso

Por exemplo,
>>> import re$e(
)arnin$ (*rom +arnin$s mo%&le):
File ",,main,,", line 1
"eprecation)arnin$: the re$e( mo%&le is
%eprecate%- please &se the re mo%&le

Neste caso, o intepretador nos sinaliza que o mdulo regex antigo e


que foi substituido por outro mais atualizado chamado re

O programa no falha, mas o programador fica ciente que


provamelmente deve reescrever seu programa usando o mdulo re
para evitar obsolecncia
O comando
O comando
raise
raise

Para sinalizar a ocorrncia de uma condio excepcional,


pode-se usar o comando raise que tem uma das formas:

raise classe

raise classe, mensagem

raise classe (mensagem)

Onde classe uma das classes de exceo definidas pelo


Python

Para saber todos os tipos de exceo consulte o manual

Se quiser uma classe genrica use a classe #(ception

Uma listagem pode ser obtida escrevendo


>>> import e(ceptions
>>> %ir(e(ceptions)
./0rithmetic#rror/, /0ssertion#rror/,
/0ttrib&te#rror/, 111
Exemplo
Exemplo
>>> raise #(ception
Traceback (most recent call last):
File "<pyshell#2>", line 1, in -topleel-
raise #(ception
#(ception
>>> raise #(ception,""e& bo%e"
Traceback (most recent call last):
File "<pyshell#3>", line 1, in -topleel-
raise #(ception,""e& bo%e"
#(ception: "e& bo%e
>>> raise #(ception(""e& 4o%e")
Traceback (most recent call last):
File "<pyshell#5>", line 1, in -topleel-
raise #(ception(""e& 4o%e")
#(ception: "e& 4o%e
Al!mas "lasses de Exceo
Al!mas "lasses de Exceo
Classe Descrio
Exception Classe base para todas as excees
AttributeError Falha no acesso ou atribuio a atributo de classe
IOError Falha no acesso a arquivo inexistente ou outros de E/S
IndexError ndice inexistente de seq!ncia
"e#Error Chave inexistente de dicion$rio
%a&eError 'ari$vel inexistente
S#ntaxError Erro de sintaxe (c)di*o errado+
,#peError Operador e&butido aplicado a ob-eto de tipo errado
'alueError
.ero/ivisionError /iviso ou &)dulo por 0ero
Operador e&butido aplicado a ob-eto de tipo certo &as
valor inapropriado
"riando !ma "lasse de Exceo
"riando !ma "lasse de Exceo

Basta criar uma classe da forma habitual derivando-a da


classe #(ception

No preciso redefinir qualquer mtodo

Ex.:
>>> class 6inha#(cecao(#(ception): pass
>>> raise 6inha#(cecao(""e& bo%e7")
Traceback (most recent call last):
File "<pyshell#11>", line 1, in -topleel-
raise 6inha#(cecao(""e& bo%e7")
6inha#(cecao: "e& bo%e7
"apt!rando Excees
"apt!rando Excees

Para capturar uma exceo possivelmente levantada por um trecho de


cdigo, pode-se usar a construo try/e(cept:
try:
Cdigo
e(cept Excees:
Cdigo de tratamento da exceo

Sendo que Excees pode ser:

Classe

Classe,var

(Classe1,...,ClasseN)

(Classe1,...,ClasseN),var

Onde:

Classe, Classe1 e ClasseN so nomes de classes de exceo

Var uma varivel qual atribuda um objeto de exceo


Exemplo #
Exemplo #
>>> try:
a 8 inp&t("#ntre com &m n&mero ")
b 8 inp&t("#ntre com o&tro n&mero ")
print a, "/", b, "8", a/b
e(cept !ero"iision#rror:
print "9oops, se$&n%o n&mero n:o po%e ser;
'ero7"
#ntre com &m n&mero 1
#ntre com o&tro n&mero 0
1 / 0 8 9oops, se$&n%o n&mero n:o po%e ser 'ero7
Exemplo $
Exemplo $
>>> try:
a 8 inp&t("#ntre com &m n&mero ")
b 8 inp&t("#ntre com o&tro n&mero ")
print a, "/", b, "8", a/b
e(cept (!ero"iision#rror,Type#rror):
print "9oops, tente noamente7"
#ntre com &m n&mero 1
#ntre com o&tro n&mero "a"
1 / a 8 9oops, tente noamente7
Exemplo %
Exemplo %
>>> try:
a 8 inp&t("#ntre com &m n&mero ")
b 8 inp&t("#ntre com o&tro n&mero ")
print a, "/", b, "8", a/b
e(cept (!ero"iision#rror,Type#rror),e:
print "9oops, %e& erro:",e
#ntre com &m n&mero 1
#ntre com o&tro n&mero "'"
1 / ' 8 9oops, %e& erro: &ns&pporte% operan%
type(s) *or /: /int/ an% /str/
&ais
&ais
except
except

possvel tratar diferentemente as diversas excees


usando duas ou mais clusulas e(cept

Se quisermos nos prevenir contra qualquer tipo de erro,


podemos usar uma clusula e(cept sem nome de classe

Outra opo usar a classe #(ception, que base para


todas as excees e portanto casa com qualquer exceo

Se no quisermos tratar um erro em uma clusula


e(cept, podemos pass-la adiante usando o comando
raise

Nesse caso, podemos usar um raise sem argumentos ou


passar explicitamente um objeto de exceo
Exemplo '
Exemplo '
>>> try:
a 8 inp&t("#ntre com &m n&mero ")
b 8 inp&t("#ntre com o&tro n&mero ")
print a, "/", b, "8", a/b
e(cept !ero"iision#rror:
print "9oops, %iis:o por 'ero"
e(cept Type#rror:
print "9oops, oc< n:o %e& &m n=mero"
e(cept:
print ""e& &m bo%e >&al>&er"
#ntre com &m n&mero ?
#ntre com o&tro n&mero *a%s?21?
"e& &m bo%e >&al>&er
Exemplo (
Exemplo (
>>> try:
a 8 inp&t("#ntre com &m n&mero ")
b 8 inp&t("#ntre com o&tro n&mero ")
print a, "/", b, "8", a/b
e(cept (!ero"iision#rror,Type#rror),e:
print "9oops, %e& erro:",e
e(cept #(ception,e:
print ""e& bo%e n:o preisto:",e
raise
#ntre com &m n&mero a
#ntre com o&tro n&mero
"e& bo%e n:o preisto: #9F +hen rea%in$ a line
Traceback (most recent call last):
File "<pyshell#3?>", line 2, in -topleel-
b 8 inp&t("#ntre com o&tro n&mero ")
#9F#rror: #9F +hen rea%in$ a line
A cl)!s!la
A cl)!s!la
else
else

possvel completar um comando try com uma clusula


else que introduz um trecho de cdigo que s executado
quando nenhuma exceo ocorre:
try:
Cdigo
e(cept Excees:
Cdigo de tratamento da exceo
else:
Cdigo executado se no ocorrem excees
Exemplo *
Exemplo *
>>> +hile Tr&e:
try:
a 8 inp&t("#ntre com &m n&mero ")
b 8 inp&t("#ntre com o&tro n&mero ")
print a, "/", b, "8", a/b
e(cept #(ception,e:
print ""e& bo%e:",e
print "Tente noamente"
else:
break
#ntre com &m n&mero 1
#ntre com o&tro n&mero (((
"e& bo%e: name /(((/ is not %e*ine%
Tente noamente
#ntre com &m n&mero 1
#ntre com o&tro n&mero ?
1 / ? 8 0
A cl)!s!la
A cl)!s!la
finally
finally

A clusula *inally pode ser usada para se assegurar que


mesmo que ocorra algum erro, uma determinada
seqncia de comandos vai ser executada

Pode ser usada para restabelecer alguma varivel para um


valor %e*a&lt, por exemplo

A clusula finally e clusulas e(cept so mutuamente


exclusivas

Excees nesse caso no so tratadas

possvel combinar ambas usando comandos try


aninhados, mas normalmente no h muito uso para isso
Exemplo +
Exemplo +
>>> try:
try:
( 8 inp&t("#ntre com &m n=mero")
*inally:
print "restabelecen%o &m alor para ("
( 8 @one
e(cept:
print ""e& bo%e"
#ntre com &m n=mero ?((
restabelecen%o &m alor para (
"e& bo%e
Iteradores
Iteradores

So maneiras genricas de implementar iteraes com


classes

Permite o uso do comando for

geralmente mais econmico do que usar uma lista pois


no preciso armazenar todos os valores, mas apenas
computar um por vez

Um iterador uma classe que implementa o mtodo


mgico ,,iter,,

um mtodo que, por sua vez, retorna um objeto que


implementa um mtodo chamado ne(t

O mtodo ne(t deve retornar o prximo valor a ser iterado

Se no h prximo valor, ne(t deve levantar a exceo


AtopBteration
Exemplo
Exemplo
>>> class 6e&Btera%or:
a 8 0
%e* ,,iter,,(sel*): ret&rn sel*
%e* ne(t(sel*):
i* sel*1a>10: raise AtopBteration
sel*1a C8 1
ret&rn sel*1a
>>> iter 8 6e&Btera%or()
>>> *or i in iter:
print i,
1 ? 2 D 3 E 5 F G 10 11
Geradores
Geradores

Geradores so funes especiais que retornam iteradores

Em resumo, uma funo geradora uma que contm o


comando yiel% valor

Uma funo geradora normalmente chamada para obter


o iterador para um comando for

O comando for automaticamente iterar sobre todos os


valores que yield retorna

Observe que o iterador produzido pela funo geradora


tal que o cdigo que gera os valores e o cdigo dentro do for
se sucedem alternadamente

Geradores so especialmente teis em cdigos recursivos


Exemplo
Exemplo
>>> %e* $era%or():
*or i in ran$e(10):
print "i 8 ", i
yiel% i
>>> *or H in $era%or():
print "H 8 ",H
i 8 0
H 8 0
i 8 1
H 8 1
1111
i 8 G
H 8 G