{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Fluxo de Controle\n",
"============\n",
"\n",
"Básico\n",
"------\n",
"\n",
"Para um dado arquivo com um programa Python, o interpretador Python começará no topo e depois processará o arquivo. Demonstramos isso com um programa simples. Por exemplo:"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"O Programa principal comeca aqui\n",
"4 * 4 = 16\n",
"Ultima linha do programa -- adeus\n"
]
}
],
"source": [
"def f(x):\n",
" \"\"\"funcao que computa e retorna x*x\"\"\"\n",
" return x * x\n",
"\n",
"print(\"O Programa principal comeca aqui\")\n",
"print(\"4 * 4 = %s\" % f(4))\n",
"print(\"Ultima linha do programa -- adeus\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A regra básica é que os comandos em um arquivo (ou função ou qualquer sequência de comandos) são processados de cima para baixo. Se vários comandos forem dados na mesma linha (separados por `;`), eles serão processados da esquerda para a direita (embora seja desencorajado ter múltiplas declarações por linha a fim de manter boa legibilidade de código.)\n",
"\n",
"Neste exemplo, o interpretador começa no topo (linha 1). Ele encontra a palavra-chave `def` e lembra para o futuro que a função `f` está definida aqui. (Ainda não executará o corpo da função, ou seja, a linha 3 - isso só acontece quando chamamos a função). O interpretador pode ver a partir do recuo onde o corpo da função acaba: o recuo na linha 5 é diferente do da primeira linha no corpo da função (linha 2), e assim o corpo da função terminou, e a execução deve continuar com essa linha. (Linhas vazias não são importantes para essa análise).\n",
"\n",
"Na linha 5, o intérprete imprimirá a saída `O programa principal comeca aqui`. Então, a linha 6 é executada. Esta linha contém a expressão `f(4)`, a qual chamará a função `f(x)`, definida na linha 1, em que `x` tomará o valor `4`. \\[Atualmente `x` é uma referência ao objeto `4`.\\] A função `f` é então executada, retornando `4*4` na linha 3. Este valor `16` é usado na linha 6 para substituir `f(4)`. Por fim, a representação *string* `%s` do objeto 16 é impressa como parte do comando de impressão na linha 6. O interpretador então passa para a linha 7 antes de o programa terminar.\n",
"\n",
"Agora vamos aprender sobre diferentes possibilidades para direcionar esse fluxo de controle ainda mais.\n",
"\n",
"### Condicionais\n",
"\n",
"Os valores `True` e `False` são objetos predefinidos especiais:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"True\n"
]
}
],
"source": [
"a = True\n",
"print(a)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"bool"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"type(a)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"False\n"
]
}
],
"source": [
"b = False\n",
"print(b)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"bool"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"type(b)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Podemos operar com esses dois valores lógicos usando a lógica booleana, por exemplo, a lógica e a operação (`and`):"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"True and True # lógica e operação"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"False"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"True and False"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"False"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"False and True"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"True and True"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"False\n"
]
}
],
"source": [
"c = a and b\n",
"print(c)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Há também o *ou* lógico (`or`) e a negação (`not` span>):"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"True or False"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"False"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"not True"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"not False"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"True and not False"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Em códigos computacionais, muitas vezes precisamos avaliar alguma expressão que seja verdadeira ou falsa (às vezes \n",
"chamada de \"predicado\"). Por exemplo:"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"x = 30 # atribui 30 a x\n",
"x > 15 # x é maior do que 15?"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"False"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"x > 42"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"x == 30 # x é igual a 30?"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"False"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"x == 42"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"not x == 42 # x não é o mesmo que 42?"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"x != 42 # x não é o mesmo que 42?"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"False"
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"x > 30 # x é maior do que 30?"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"x >= 30 # x é maior do que ou igual a 30?"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Se-então-senão\n",
"------------\n",
"\n",
"##### Informação adicional\n",
"\n",
"- Introdução à estrutura condicional `if-then` em [Python tutorial, seção 4.1](http://docs.python.org/tutorial/controlflow.html#if-statements)\n",
"\n",
"A declaração `if` permite execução condicional de código. Por exemplo:"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"a é positivo\n"
]
}
],
"source": [
"a = 34\n",
"if a > 0:\n",
" print(\"a é positivo\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A declaração `if` também pode ter uma ramificação `else` que é executada se a condição estiver errada:"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"a é positivo\n"
]
}
],
"source": [
"a = 34\n",
"if a > 0:\n",
" print(\"a é positivo\")\n",
"else:\n",
" print(\"a é nao-positivo (i.e. negativo ou zero)\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Finalmente, existe a palavra-chave `elif` (leia como \"else if\") que permite verificar várias possibilidades (exclusivas):"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"a é positivo\n"
]
}
],
"source": [
"a = 17\n",
"if a == 0:\n",
" print(\"a é zero\")\n",
"elif a < 0:\n",
" print(\"a é negativo\")\n",
"else:\n",
" print(\"a é positivo\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Laço `for`\n",
"--------\n",
"\n",
"##### Informação adicional\n",
"\n",
"- Introdução a laços `for` [Python tutorial, seção 4.2](http://docs.python.org/tutorial/controlflow.html#for-statements)\n",
"\n",
"O laço `for` permite-nos iterar sobre uma sequencia (isto poderia ser uma *string* ou lista, por exemplo). Aqui está um exemplo:"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"cão CÃO\n",
"gato GATO\n",
"rato RATO\n"
]
}
],
"source": [
"for animal in ['cão','gato','rato']:\n",
" print(animal, animal.upper())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Juntamente com o comando `range()`, pode-se iterar sobre inteiros crescentes:"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"5\n",
"6\n",
"7\n",
"8\n",
"9\n"
]
}
],
"source": [
"for i in range(5,10):\n",
" print(i)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Laço `while`\n",
"----------\n",
"\n",
"A palavra-chave `while` permite-nos repetir uma operação enquanto uma condição é verdadeira. Suponha que quiséssemos saber por quantos anos teremos que guardar 100 reais em uma poupança para alcançar 200 reais simplesmente \n",
"por uma taxa de juros de 5% ao ano. Aqui está um programa para computar isso:"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Preciso de 15 anos para alcançar 207.89281794113688 reais.\n"
]
}
],
"source": [
"montante = 100 # em BRL\n",
"taxa = 1.05 # 5% a.a. juros\n",
"anos = 0\n",
"while montante < 200: # repita até que 200 seja alcancado\n",
" montante = montante * taxa\n",
" anos = anos + 1\n",
"print('Preciso de', anos, 'anos para alcançar', montante, 'reais.')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Operadores relacionais (comparações) nas declarações `if` e `while`\n",
"-------------------------------------------------- -----------------------------------------\n",
"\n",
"A forma geral de `if` e `while` é a mesma: seguindo a palavra-chave `if` ou `while`, existe uma *condição* seguida de dois pontos. Na próxima linha, um novo (e, portanto, indentado!) bloco de comandos começa a ser executado se a condição for `True`).\n",
"\n",
"Por exemplo, a condição pode ser a igualdade de duas variáveis `a1` e `a2`, expressa como `a1 == a2`:"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"a1 e a2 são iguais\n"
]
}
],
"source": [
"a1 = 42\n",
"a2 = 42\n",
"if a1 == a2:\n",
" print(\"a1 e a2 são iguais\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Outro exemplo é testar se `a1` e `a2` não são os mesmos. Para isso, temos duas possibilidades. A opção número 1 usa o *operador de desigualdade* `!=`:"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"if a1 != a2:\n",
" print(\"a1 e a2 são diferentes\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A opção 2 usa a palavra-chave `not` à frente da condição:"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"if not a1 == a2:\n",
" print(\"a1 e a2 são diferentes\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Comparações para \"maior\" (`>`), \"menor\" (`<`) e \"maior ou igual a\" (`>=`) e \"menor ou igual a\" (`<=`) são diretos.\n",
"\n",
"Finalmente, podemos usar os operadores lógicos \"`and`\" e \"`or`\" para combinar condições:"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Ou a é maior do que 10, ou b é menor do que -5, ou ambos.\n"
]
}
],
"source": [
"a = 11\n",
"b = -3\n",
"if a > 10 and b > 20:\n",
" print(\"A é maior do que 10 e b é maior do que 20\")\n",
"if a > 10 or b < -5:\n",
" print(\"Ou a é maior do que 10, ou \"\n",
" \"b é menor do que -5, ou ambos.\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Use o *prompt* do Python para experimentar estas comparações e expressões lógicas. Por exemplo:"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"bastante frio\n"
]
}
],
"source": [
"T = -12.5\n",
"if T < -20:\n",
" print(\"muito frio\")\n",
"\n",
"if T < -10:\n",
" print(\"bastante frio\")"
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"False"
]
},
"execution_count": 34,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"T < -20"
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 35,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"T < -10"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Exceções\n",
"----------\n",
"\n",
"Mesmo que uma declaração ou expressão seja sintaticamente correta, ela pode causar um erro quando uma tentativa é feita para executá-la. Os erros detectados durante a execução são chamados *exceções* e não são necessariamente fatais: exceções podem ser *capturadas* e tratadas no programa. A maioria das exceções não são tratadas pelos programas, no entanto, e resultam em mensagens de erro como as mostradas aqui:"
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {},
"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[0;32m----> 1\u001b[0;31m \u001b[0;36m10\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m/\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;31mZeroDivisionError\u001b[0m: division by zero"
]
}
],
"source": [
"10 * (1/0)"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {},
"outputs": [
{
"ename": "NameError",
"evalue": "name 'spam' is not defined",
"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;36m4\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mspam\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;31mNameError\u001b[0m: name 'spam' is not defined"
]
}
],
"source": [
"4 + spam*3"
]
},
{
"cell_type": "code",
"execution_count": 38,
"metadata": {},
"outputs": [
{
"ename": "TypeError",
"evalue": "must be str, not int",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mTypeError\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;34m'2'\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;31mTypeError\u001b[0m: must be str, not int"
]
}
],
"source": [
"'2' + 2"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Excepção esquemática capturando todas as opções"
]
},
{
"cell_type": "code",
"execution_count": 39,
"metadata": {},
"outputs": [
{
"ename": "IndentationError",
"evalue": "expected an indented block (, line 3)",
"output_type": "error",
"traceback": [
"\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m3\u001b[0m\n\u001b[0;31m except ArithmeticError:\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mIndentationError\u001b[0m\u001b[0;31m:\u001b[0m expected an indented block\n"
]
}
],
"source": [
"try:\n",
" # corpo de código\n",
"except ArithmeticError:\n",
" # o que fazer se houver erro de aritmética\n",
"except IndexError, the_exception:\n",
" # the_exception refere-se à exceção neste bloco\n",
"except:\n",
" # o que fazer para qualquer outra exceção\n",
"else: # opcional\n",
" # o que fazer se nenhuma exceção for lançada\n",
"\n",
"try:\n",
" # corpo de código\n",
"finally:\n",
" # o que fazer SEMPRE"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A partir do Python 2.5, você pode usar a instrução `with` para simplificar a escrita do código para algumas funções predefinidas, em particular a função `open` para abrir arquivos: veja .\n",
"\n",
"Exemplo: tentaremos abrir um arquivo que não existe e o Python criará uma exceção do tipo `IOError`, que significa erro de entrada/saída:"
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {},
"outputs": [
{
"ename": "FileNotFoundError",
"evalue": "[Errno 2] No such file or directory: 'filenamethatdoesnotexist'",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mFileNotFoundError\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[0mf\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mopen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"filenamethatdoesnotexist\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"r\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;31mFileNotFoundError\u001b[0m: [Errno 2] No such file or directory: 'filenamethatdoesnotexist'"
]
}
],
"source": [
"f = open(\"filenamethatdoesnotexist\", \"r\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Se estivéssemos escrevendo um aplicativo com uma interface onde o usuário deve digitar ou selecionar um nome de arquivo, não gostaríamos que o aplicativo parasse se o arquivo não existisse. Em vez disso, precisamos capturar esta exceção e agir para tratá-la (informando, por exemplo, o usuário que um arquivo com tal nome não existe e perguntar se ele quer tentar outro nome de arquivo). Aqui está o esqueleto para capturar esta exceção:"
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Arquivo não pode ser aberto.\n"
]
}
],
"source": [
"try:\n",
" f = open(\"arquivo_inexistente\",\"r\")\n",
"except IOError:\n",
" print(\"Arquivo não pode ser aberto.\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Há muito mais para ser dito sobre exceções e o uso delas em programas maiores. Comece lendo o [Capítulo 8 do Python Tutorial: Erros e Exceções](http://docs.python.org/tutorial/errors.html#errors-and-exceptions) se você tiver interesse.\n",
"\n",
"### Lançando Exceções\n",
"\n",
"Possibilidades de lançar uma exceção:\n",
"\n",
"- `raise OverflowError`\n",
"\n",
"- `raise OverflowError, Bath is full` (estilo antigo, desencorajado)\n",
"\n",
"- `raise OverflowError(Bath is full)`\n",
"\n",
"- `e = OverflowError(Bath is full); raise e`\n",
"\n",
"#### Hierarquia de exceções\n",
"\n",
"As exceções padrão são organizadas em uma hierarquia de herança, e.g. `OverflowError` é uma subclasse de `ArithmeticError`. Isso pode ser visto ao examinarmos `help('exceptions')`, por exemplo. Você pode derivar suas próprias exceções de qualquer um dos padrões. É um bom estilo que cada módulo defina sua própria exceção de base."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Criando as suas próprias exceções\n",
"\n",
"- Você pode e deve derivar suas próprias exceções a partir de uma exceção predefinida.\n",
"\n",
"- Para ver quais exceções predefenidas existem, procure no módulo de exceções (tente `help('exceptions')`) ou acesse .\n",
"\n",
"### LBYL vs EAFP\n",
"\n",
"- LBYL (Look Before You Leap = Pense duas vezes antes de agir) *versus*\n",
"\n",
"- EAFP (Easer to ask forgiveness than permission = Facilidade de pedir perdão do que permissão)"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"numerador = 7\n",
"denominador = 0"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Exemplo para LBYL:"
]
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Oops...\n"
]
}
],
"source": [
"if denominador == 0:\n",
" print(\"Oops...\")\n",
"else:\n",
" print(numerador/denominador)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"EAFP:"
]
},
{
"cell_type": "code",
"execution_count": 44,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Oops...\n"
]
}
],
"source": [
"try:\n",
" print(numerador/denominador)\n",
"except ZeroDivisionError:\n",
" print(\"Oops...\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"O que a documentação do Python diz sobre EAFP:\n",
"\n",
"Veja \n",
"\n",
"O que a documentação do Python diz sobre LBYL:\n",
"\n",
"Veja \n",
"\n",
"EAFP é a maneira \"Pythônica\"."
]
}
],
"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.4"
}
},
"nbformat": 4,
"nbformat_minor": 1
}