Nas partes anteriores vimos os tipos de datos e os operadores, controle de fluxo e funções. Neste último capítulo vemos as **classes e objetos**, os **iteradores**, o **escopo de variáveis**, os **módulos e pacotes**, o manejo de erros com **try... except**, as **palavras reservadas** e o **Zen de Python**.
Aviso: Este post foi traduzido para o português usando um modelo de tradução automática. Por favor, me avise se encontrar algum erro.
📚 **Esta entrada faz parte da série _Guía completa de Python_**, dividida em três capítulos que são lidos em ordem:
> * Parte 1: Tipos de datos
* Parte 2: Operadores, control de fluxo y funciones
* 👉 **Parte 3: Clases, objetos y temas avançados**
7. Classes e objetos
Python é uma linguagem de programação orientada a objetos. Quase tudo em Python é um objeto, com seus atributos e métodos.
Uma classe é como um construtor de objetos ou um “plano” para criar objetos.
Para criar uma classe, usa-se a palavra reservada class
InputPythonclass Clase:variable = 'MaximoFN'Copied
Uma vez criada a classe, pode-se criar um objeto dessa classe
InputPythonobjeto = Clase()Clase.variableCopied
'MaximoFN'
Normalmente as classes têm uma função inicial, que é executada quando um objeto da classe é criado. Esta função denomina-se *dunder init* e escreve-se __init__(). À função *dunder init* tem de ser sempre passada a variável self, que indica a própria classe, e, em seguida, as variáveis que se queiram passar
Com esta função, normalmente se inicializam as variáveis das classes, ou executa-se o código necessário quando um objeto da classe é criado
InputPythonclass Persona:def __init__(self, nombre, edad):self.nombre = nombreself.edad = edadobjeto_persona = Persona("Miguel", 36)print(objeto_persona.nombre)print(objeto_persona.edad)Copied
Miguel36
Além da função inicial *dunder init*, podem ser criadas mais funções. Essas funções são chamadas de *métodos* da classe. A esses *métodos* sempre é necessário passar a variável self
InputPythonclass Persona:def __init__(self, nombre, edad):self.nombre = nombreself.edad = edaddef saludar(self):print(f'Hola mi nombre es {self.nombre} y tengo {self.edad} años')objeto_persona = Persona("Miguel", 36)objeto_persona.saludar()Copied
Hola mi nombre es Miguel y tengo 36 años
A variável self não precisa ser chamada self, pode ter qualquer nome, mas dentro de cada classe tem que ser sempre o mesmo. Porém, por convenção, costuma-se usar self
InputPythonclass Persona:def __init__(yo_mismo, nombre, edad):yo_mismo.nombre = nombreyo_mismo.edad = edaddef saludar(yo_mismo):print(f'Hola mi nombre es {yo_mismo.nombre} y tengo {yo_mismo.edad} años')objeto_persona = Persona("Miguel", 36)objeto_persona.saludar()Copied
Hola mi nombre es Miguel y tengo 36 años
Podem ser modificáveis as variáveis dos objetos
InputPythonobjeto_persona.nombre = 'Marta'objeto_persona.saludar()Copied
Hola mi nombre es Marta y tengo 36 años
Mesmo removê-las
InputPythondel objeto_persona.nombreCopied
Também se pode eliminar o objeto inteiro
InputPythondel objeto_personaCopied
Se, por exemplo, quisermos fazer a estrutura da classe, mas não quisermos, por enquanto, codificar o interior, podemos usar pass
InputPythonclass Persona:passobjeto_persona = Persona()Copied
7.1. Herança
A herança nos permite definir uma classe que herde todos os métodos e propriedades de outra classe.
A **classe pai** é a classe da qual se herda, também chamada **classe base**.
A **classe filha** é a classe que herda de outra classe, também chamada de **classe derivada**.
Criamos uma classe pai
InputPythonclass Persona:def __init__(self, nombre, apellido):self.nombre = nombreself.apellido = apellidodef imprimir_nombre(self):print(f'Me llamo {self.nombre} {self.apellido}')objeto_padre = Persona("Laura", "Perez")objeto_padre.imprimir_nombre()Copied
Me llamo Laura Perez
Para criar a classe filha, é preciso indicar entre parênteses, na hora de declarar a classe, de que classe ela herda.
InputPythonclass Estudiante(Persona):passCopied
E no momento de criar o objeto da classe filha, são passados os parâmetros que a classe pai precisa
InputPythonobjeto_hijo = Estudiante("Mariano", "Sanz")objeto_hijo.imprimir_nombre()Copied
Me llamo Mariano Sanz
Até agora, a classe filha herdou as funções da classe pai, mas podemos modificá-las reescrevendo-as. Por exemplo, reescrevendo a função *dunder init*.
Se a função *dunder init* for reescrita, se quisermos chamar a função *dunder init* da classe pai, temos de a chamar.
Para isso, há duas maneiras: uma é por meio do nome da classe pai. Nesse caso, é preciso passar a variável self.
InputPythonclass Estudiante(Persona):def __init__(self, nombre, apellido):Persona.__init__(self, nombre, apellido)objeto_hijo = Estudiante("Mariano", "Sanz")objeto_hijo.imprimir_nombre()Copied
Me llamo Mariano Sanz
Outra forma é por meio de super(), neste caso não é necessário passar a variável self
InputPythonclass Estudiante(Persona):def __init__(self, nombre, apellido):super().__init__(nombre, apellido)objeto_hijo = Estudiante("Mariano", "Sanz")objeto_hijo.imprimir_nombre()Copied
Me llamo Mariano Sanz
Ao modificar as funções, pode-se adicionar novo código
InputPythonclass Estudiante(Persona):def __init__(self, nombre, apellido, curso):Persona.__init__(self, nombre, apellido)self.curso = cursodef imprimir_nombre(self):Persona.imprimir_nombre(self)print(f'Estoy en el curso número {self.curso}')objeto_hijo = Estudiante("Mariano", "Sanz", 4)objeto_hijo.imprimir_nombre()Copied
Me llamo Mariano SanzEstoy en el curso número 4
Por fim, podem ser adicionados novos métodos
InputPythonclass Estudiante(Persona):def __init__(self, nombre, apellido, curso):Persona.__init__(self, nombre, apellido)self.curso = cursodef imprimir_nombre(self):Persona.imprimir_nombre(self)print(f'Estoy en el curso número {self.curso}')def imprimir_estudiante(self):print(f"Soy un estudiante del curso número {self.curso}")objeto_hijo = Estudiante("Mariano", "Sanz", 4)objeto_hijo.imprimir_nombre()objeto_hijo.imprimir_estudiante()Copied
Me llamo Mariano SanzEstoy en el curso número 4Soy un estudiante del curso número 4
7.2. Sobrecarga de operadores
Podemos definir operações básicas, como a soma, entre vários objetos de uma classe. Por exemplo, se temos uma classe que representa um vetor, podemos definir a soma e a multiplicação entre objetos dessa classe
InputPythonclass Vector:def __init__(self, x, y):self.x = xself.y = ydef __add__(self, other):return Vector(self.x + other.x, self.y + other.y)def __mul__(self, other):return Vector(self.x * other.x, self.y * other.y)def __str__(self):return f"Vector ({self.x}, {self.y})"v1 = Vector(1, 2)v2 = Vector(3, 4)print(v1 + v2) # Vector (4, 6)print(v1 * v2) # Vector (3, 8)Copied
Vector (4, 6)Vector (3, 8)
Todas as possíveis sobrecargas de operadores são:
__add__(self, other): sobrecarrega o operador de soma (+).__sub__(self, other): sobrecarga o operador de subtração (-).__mul__(self, other): sobrecarrega o operador de multiplicação (*).__truediv__(self, other): sobrecarrega o operador de divisão (/).__floordiv__(self, other): sobrecarrega o operador de divisão inteira arredondada (//).__mod__(self, other): sobrecarrega o operador de módulo (%).__divmod__(self, other): sobrecarrega a funçãodivmod().__pow__(self, other): sobrecarrega o operador de potência (**).__lshift__(self, other): sobrecarrega o operador de deslocamento à esquerda (<<).__rshift__(self, other): sobrecarrega o operador de deslocamento à direita (>>).__and__(self, other): sobrecarrega o operador and (&).__or__(self, other): sobrecarga o operador or (|).__xor__(self, other): sobrecarrega o operador de xor (^).*__lt__(self, other): sobrecarrega o operador de comparação menor que (<).__le__(self, other): sobrecarrega o operador de comparação menor ou igual que (<=).__eq__(self, other): sobrecarrega o operador de comparação igual a (==).__ne__(self, other): sobrecarrega o operador de comparação diferente de (!=).__gt__(self, other): sobrecarrega o operador de comparação maior que (>).__ge__(self, other): sobrecarrega o operador de comparação maior ou igual que (>=).__neg__(self): sobrecarrega o operador de negação (-).__pos__(self): sobrecarrega o operador de posição (+).__abs__(self): sobrecarrega a funçãoabs().__invert__(self): sobrecarrega o operador de inversão (~).__complex__(self): sobrecarrega a funçãocomplex().__int__(self): sobrecarrega a funçãoint().__float__(self): sobrecarrega a funçãofloat().
7.3. Iteradores personalizados
Como vimos na seção 2 (Tipos de datos de Python), existem alguns tipos de dados sobre os quais se pode iterar. Mas podemos criar nossa própria classe iterável, desde que tenha as funções __len__ e __getitem__
InputPythonclass custonIterator:def __init__(self, n):self.items = [i for i in range(n)]def __len__(self):return len(self.items)def __getitem__(self, index):return self.items[index]iterator = custonIterator(10)print(len(iterator)) # 10print(iterator[0]) # 0print(iterator[1]) # 1Copied
1001
Agora podemos iterar com o objeto da nossa classe com laços for, por exemplo
InputPythonfor i in iterator:print(i, end=" ") # 0 1 2 3 4 5 6 7 8 9Copied
0 1 2 3 4 5 6 7 8 9
7.4. Chamada a objetos como funções
Pode nos interessar chamar um objeto de uma função como se fosse uma classe. Isso pode ser conseguido adicionando a função __call__ à classe
InputPythonclass potencia:def __init__(self, base):self.base = basedef __call__(self, potencia):return self.base ** potenciapotencia_cuadrado = potencia(2)print(potencia_cuadrado(3)) # 8Copied
8
7.5. Atributos e funções privados
Quando criamos uma classe, podemos fazer com que alguns atributos ou funções sejam privados e não possam ser acessados de fora da classe; para isso, é necessário adicionar __ antes do atributo ou método
InputPythonclass Privados:def __init__(self):self.publico = "Soy público"self.__privado = "Soy privado"def getPrivado(self):return self.__privadodef setPrivado(self, valor):self.__privado = valordef __funcion_privada(self):return "Soy una función privada"def funcion_publica(self):return self.__funcion_privada()privados = Privados()print("Acceso al atributo publico: ", end="")try:print(f"{privados.publico}")except:print(" No se puede acceder al atributo privado")print("Acceso al atributo privado: ", end="")try:print(f"{privados.__privado}")except:print(" No se puede acceder al atributo privado")print("Acceso al atributo privado mediante el accesor: ", end="")try:print(f"{privados.getPrivado()}")except:print(" No se puede acceder al atributo privado mediante el accesor")print("Llamada a la función privada: ", end="")try:print(f"{privados.__funcion_privada()}")except:print(" No se puede llamar a la función privada")print("Llamada a la función pública: ", end="")try:print(f"{privados.funcion_publica()}")except:print(" No se puede llamar a la función pública")Copied
Acceso al atributo publico: Soy públicoAcceso al atributo privado: No se puede acceder al atributo privadoAcceso al atributo privado mediante el accesor: Soy privadoLlamada a la función privada: No se puede llamar a la función privadaLlamada a la función pública: Soy una función privada
8. Iteradores
Um iterador é um objeto que contém um número contável de valores.
Um iterador é um objeto sobre o qual se pode iterar, o que significa que pode percorrer todos os elementos.
Tecnicamente, em Python, um iterador é um objeto que implementa o protocolo do iterador, que consiste nos métodos __iter__() e __next__().
As listas, tuplas, dicionários e conjuntos são todos objetos iteráveis. São contêineres iteráveis dos quais se pode obter um iterador.
Todos esses objetos têm um método iter() que é usado para obter um iterador:
InputPythontupla = ("manzana", "plátano", "cereza")iterable = iter(tupla)print(next(iterable))print(next(iterable))print(next(iterable))Copied
manzanaplátanocereza
InputPythonstring = "plátano"iterable = iter(string)print(next(iterable), end=' ')print(next(iterable), end=' ')print(next(iterable), end=' ')print(next(iterable), end=' ')print(next(iterable), end=' ')print(next(iterable), end=' ')print(next(iterable), end=' ')Copied
p l á t a n o
O laço for na verdade cria um objeto iterador e executa o método next() em cada iteração.
InputPythontupla = ("manzana", "plátano", "cereza")for x in tupla:print(x)Copied
manzanaplátanocereza
InputPythonstring = "plátano"for x in string:print(x, end=' ')Copied
p l á t a n o
8.1. Criar um objeto iterador
Para criar um objeto/classe como iterador, é preciso implementar os métodos __iter__() e __next__().
InputPythonclass Numeros:def __iter__(self):self.a = 1return selfdef __next__(self):x = self.aself.a += 1return xobjeto_iterador = Numeros()iterador = iter(objeto_iterador)print(next(iterador), end=' ')print(next(iterador), end=' ')print(next(iterador), end=' ')print(next(iterador), end=' ')print(next(iterador), end=' ')Copied
1 2 3 4 5
O exemplo anterior continuaria para sempre se tivesse chamadas suficientes a next(), ou se fosse usado num ciclo for.
Para evitar que a iteração continue para sempre, podemos usar a declaração StopIteration.
No método __next__(), podemos adicionar uma condição de terminação para gerar um erro se a iteração for realizada um número específico de vezes:
InputPythonclass Numeros:def __iter__(self):self.a = 1return selfdef __next__(self):if self.a <= 20:x = self.aself.a += 1return xelse:raise StopIterationobjeto_iterador = Numeros()iterador = iter(objeto_iterador)for x in iterador:print(x, end=' ')Copied
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
8.2. Iterar obtendo o índice e o valor
Podemos iterar por um objeto iterável obtendo em cada iteração seu índice e seu valor por meio do método enumerate()
InputPythonstring = "MaximoFN"for index, valor in enumerate(string):print(f"En la posición {index}, está el caracter {valor}")Copied
En la posición 0, está el caracter MEn la posición 1, está el caracter aEn la posición 2, está el caracter xEn la posición 3, está el caracter iEn la posición 4, está el caracter mEn la posición 5, está el caracter oEn la posición 6, está el caracter FEn la posición 7, está el caracter N
8.3. Iterar simultaneamente sobre dois objetos iteráveis
Se tivermos dois objetos iteráveis, do mesmo comprimento, podemos iterar pelos dois ao mesmo tempo por meio do método zip()
InputPythonstring1 = 'MaximoFN__'string2 = 'PythonPost'if len(string1) == len(string2):for valor1, valor2 in zip(string1, string2):print(f"En el primer string hay {valor1}, en el segundo string hay {valor2}")Copied
En el primer string hay M, en el segundo string hay PEn el primer string hay a, en el segundo string hay yEn el primer string hay x, en el segundo string hay tEn el primer string hay i, en el segundo string hay hEn el primer string hay m, en el segundo string hay oEn el primer string hay o, en el segundo string hay nEn el primer string hay F, en el segundo string hay PEn el primer string hay N, en el segundo string hay oEn el primer string hay _, en el segundo string hay sEn el primer string hay _, en el segundo string hay t
9. Escopo de variáveis
Uma variável só está disponível dentro da região em que é criada. Isso é chamado de *escopo*
9.1. Escopo local
Uma variável criada dentro de uma função pertence ao âmbito local dessa função e só pode ser usada dentro dessa função.
InputPythondef funcion():x = 300print(x)funcion()Copied
300
A variável x não está disponível fora da função, mas está disponível para qualquer função dentro dela
InputPythondef funcion():x = 300def funcion_interna():print(x)funcion_interna()funcion()Copied
300
9.2. Alcance global
Uma variável criada no corpo principal do código Python é uma variável global e pertence ao escopo global.
As variáveis globais estão disponíveis a partir de qualquer escopo, global e local.
InputPythonx = 300def funcion():print(f'Ámbito local: {x}')funcion()print(f'Ámbito global: {x}')Copied
Ámbito local: 300Ámbito global: 300
Se forem criadas duas variáveis, uma global e outra local, ambas com o mesmo nome, o Python as criará como duas variáveis distintas
InputPythonx = 300def funcion():x = 200print(f'Variable local: {x}')funcion()print(f'Variable global: {x}')Copied
Variable local: 200Variable global: 300
Se for necessário criar uma variável global, mas ela estiver declarada no escopo local, pode-se usar a palavra-chave global.
A palavra-chave global torna a variável global.
InputPythondef funcion():global xx = 300funcion()print(f'Variable global: {x}')Copied
Variable global: 300
Além disso, o uso da palavra-chave global permite realizar uma alteração em uma variável global dentro de uma função.
InputPythonx = 300def funcion():global xx = 200funcion()print(f'Variable global: {x}')Copied
Variable global: 200
10. Módulos
Um módulo é um arquivo que contém um conjunto de funções que você deseja incluir em sua aplicação.
Para criar um módulo, simplesmente salve o código que deseja em um arquivo com a extensão .py
Dica: Nos notebooks Jupyter (Colab é um notebook Jupyter online), se escrevemos o caractere
!antes de um comando, poderemos executar comandos de terminal
Primeiro vamos ver em que diretório estamos, para isso usamos o comando pwd (*print working directory*)
InputPython!pwdCopied
/home/wallabot/Documentos/web/portafolio/posts
Vamos criar uma pasta para criar nossos módulos com o comando mkdir (make directory)
InputPython!mkdir introduccion_pythonCopied
A seguir, vamos ver quais arquivos há em nossa pasta. Isso faremos por meio do comando ls (*list*)
InputPython!ls introduccion_pythonCopied
Vemos que ela está vazia, criamos um novo arquivo .py no qual vamos criar o nosso módulo
InputPython%%writefile introduccion_python/modulo1.pydef funcion_del_modulo(nombre):print("Hola, " + nombre)Copied
Writing introduccion_python/modulo1.py
Vamos ver novamente quais arquivos existem na nossa pasta
InputPython!ls introduccion_pythonCopied
modulo1.py __pycache__
Vemos que um arquivo módulo1.py foi criado. Já podemos usá-lo
Para usar um módulo externo, é preciso usar a palavra import. Para usar as funções do módulo, é preciso primeiro colocar o nome do módulo, um . e, em seguida, o nome da função que se quer usar
InputPythonimport introduccion_python.modulo1introduccion_python.modulo1.funcion_del_modulo('MaximoFN')Copied
Hola, MaximoFN
Se quisermos que, dentro do nosso código, o módulo tenha um nome específico, podemos usar a palavra as
InputPythonimport introduccion_python.modulo1 as mod1mod1.funcion_del_modulo('MaximoFN')Copied
Hola, MaximoFN
Se o módulo tiver várias funções, mas quisermos importar apenas uma, podemos fazer isso mediante o uso das palavras from e import. A forma seria
from <módulo> import <função>Neste caso, não é necessário indicar o nome do módulo ao chamar a função
InputPython%%writefile introduccion_python/modulo2.pydef funcion1_del_modulo(nombre):print("Hola, " + nombre + ", funcion 1")def funcion2_del_modulo(nombre):print("Hola, " + nombre + ", funcion 2")def funcion3_del_modulo(nombre):print("Hola, " + nombre + ", funcion 3")Copied
Writing introduccion_python/modulo2.py
InputPythonfrom introduccion_python.modulo2 import funcion2_del_modulofuncion2_del_modulo('MaximoFN')Copied
Hola, MaximoFN, funcion 2
Não podemos usar apenas módulos criados por nós, mas também módulos já instalados (built-in modules)
Por exemplo, podemos usar o módulo platform
InputPythonimport platformx = platform.system()xCopied
'Linux'
10.1. Pontos de entrada: arquivos como módulos e não como scripts
Vamos agora criar um arquivo chamado módulo3.py
InputPython%%writefile introduccion_python/modulo3.pyprint("Hola desde modulo3")def funcion_del_modulo():return "Hola desde la función del modulo3"Copied
Overwriting introduccion_python/modulo3.py
Se agora importamos modulo3.py para usar a função funcion_del_modulo vejamos o que ocorre
InputPythonimport introduccion_python.modulo3 as mod3print(mod3.funcion_del_modulo())Copied
Hola desde modulo3Hola desde la función del modulo3
Vemos que foi executado o print de modulo3.py, mas não é o que queríamos; isso acontece porque, ao chamar o arquivo modulo3.py, o Python o executa como um script
Mas o que acontece se quisermos executar introduccion_python/main.py como um script?
InputPython!python introduccion_python/modulo3.pyCopied
Hola desde modulo3
Vemos que apenas o print é executado, mas não a função funcion_del_modulo. Se quisermos ter a dualidade de funcionalidade do arquivo modulo3.py, isto é, que possamos importá-lo a partir de outro módulo sem que ele seja executado como um script e executá-lo isoladamente, e que seja executada a função que nós queremos, usa-se um entry point. Isto é, usar a condição if __name__ == '__main__': e, em seguida, indicar o que queremos que seja executado. Vejamos com um exemplo, vou reescrever o arquivo modulo3.py
InputPython%%writefile introduccion_python/modulo3.pyprint("Hola desde modulo3")def funcion_del_modulo():return "Hola desde la función del modulo3"if __name__ == "__main__":funcion_del_modulo()Copied
Overwriting introduccion_python/modulo3.py
Se agora eu chamar main.py de outro módulo, o print não será mais executado
InputPythonimport introduccion_python.modulo3 as mod3print(mod3.funcion_del_modulo())Copied
Hola desde la función del modulo3
E se eu o executar como um script independente, a função función_del_modulo será executada
InputPython!python introduccion_python/modulo3.pyCopied
Hola desde modulo3
11. Pacotes
Em Python, podemos criar nossos próprios pacotes; para isso, criamos uma pasta com o nome do pacote
InputPython!mkdir mi_paquete_de_pythonCopied
Criamos agora dois arquivos dentro
InputPython!touch mi_paquete_de_python/modulo1.py mi_paquete_de_python/modulo2.pyCopied
E escrevemos neles
InputPython%%writefile mi_paquete_de_python/modulo1.pydef funcion1():print("Hola desde la función 1 del módulo 1")def funcion2():print("Hola desde la función 2 del módulo 1")Copied
Overwriting mi_paquete_de_python/modulo1.py
InputPython%%writefile mi_paquete_de_python/modulo2.pydef funcion1():print("Hola desde la función 1 del módulo 2")def funcion2():print("Hola desde la función 2 del módulo 2")Copied
Overwriting mi_paquete_de_python/modulo2.py
Agora podemos chamar as funções do nosso pacote
InputPythonfrom mi_paquete_de_python import modulo1 as mod1from mi_paquete_de_python import modulo2 as mod2mod1.funcion1()mod1.funcion2()mod2.funcion1()mod2.funcion2()Copied
Hola desde la función 1 del módulo 1Hola desde la función 2 del módulo 1Hola desde la función 1 del módulo 2Hola desde la función 2 del módulo 2
Mas o que acontece se o nosso pacote tiver dezenas de arquivos com funções que queremos usar? Teríamos que importar todos os arquivos um a um. Para evitar isso, pode-se criar um arquivo __init__.py dentro do pacote onde se faça toda essa importação de arquivos
InputPython!touch mi_paquete_de_python/__init__.pyCopied
InputPython%%writefile mi_paquete_de_python/__init__.pyimport modulo1import modulo2Copied
Overwriting mi_paquete_de_python/__init__.py
Agora podemos simplesmente importar nosso pacote, que internamente já importou todos os módulos
InputPythonimport mi_paquete_de_python as mi_paquetemi_paquete.modulo1.funcion1()mi_paquete.modulo1.funcion2()mi_paquete.modulo2.funcion1()mi_paquete.modulo2.funcion2()Copied
Hola desde la función 1 del módulo 1Hola desde la función 2 del módulo 1Hola desde la función 1 del módulo 2Hola desde la función 2 del módulo 2
Dessa maneira, só temos que fazer um import
12. Try... except
Quando ocorre um erro, ou uma exceção, como realmente se chama, o Python normalmente o capturará e gerará uma mensagem de erro.
Essas exceções podem ser tratadas usando as declarações try e except
InputPythontry:print(variable_no_declarada)except:print("Ha ocurrido una excepción")Copied
Ha ocurrido una excepción
Como o bloco try gera um erro, então o bloco except será executado
Sem o bloco try, o programa travaria e geraria um erro
Podem ser definidos quantos blocos de exceção se desejar, por exemplo, se quiser executar um bloco de código especial para um tipo especial de erro
InputPythontry:print(variable_no_declarada)except NameError:print("La variable 'variable_no_declarada' no está definida")except:print("Algo inesperado ha ocurrido")Copied
La variable 'variable_no_declarada' no está definida
Você pode usar a palavra else para indicar o caso em que não tenha ocorrido um erro
InputPythontry:print('MaximoFN')except NameError:print("Ha ocurrido una excepción")else:print('Todo OK')Copied
MaximoFNTodo OK
com a palavra finally será executado um código ao final, tenha ocorrido uma exceção ou não
InputPythontry:print(variable_no_declarada)except:print("Ha ocurrido una excepción")finally:print("'try except' finallizado")Copied
Ha ocurrido una excepción'try except' finallizado
Isso pode ser útil para fechar objetos e limpar recursos
InputPythonclass Clase:variable = 'MaximoFN'objeto = Clase()try:print(Clase.mi_variable)except:print("Ha ocurrido una excepción")finally:del objetoCopied
Ha ocurrido una excepción
12.1. Criar uma exceção
Como desenvolvedor Python, é possível optar por lançar uma exceção se ocorrer uma condição.
Para lançar (ou gerar) uma exceção, é necessário usar a palavra-chave raise
InputPythondef division(numerador, denominador):if denominador == 0:raise Exception("El denominador no puede ser 0")return numerador/denominadorprint(division(10, 0))Copied
---------------------------------------------------------------------------Exception Traceback (most recent call last)<ipython-input-16-33fb6066fa78> in <module>5 return numerador/denominador6----> 7 print(division(10, 0))<ipython-input-16-33fb6066fa78> in division(numerador, denominador)1 def division(numerador, denominador):2 if denominador == 0:----> 3 raise Exception("El denominador no puede ser 0")45 return numerador/denominadorException: El denominador no puede ser 0
É possível definir que tipo de erro gerar e o texto que será mostrado ao usuário
InputPythondef division(numerador, denominador):if denominador == 0:raise TypeError("El denominador no puede ser 0")return numerador/denominadorprint(division(10, 0))Copied
---------------------------------------------------------------------------TypeError Traceback (most recent call last)<ipython-input-17-26bfa63ae44c> in <module>5 return numerador/denominador6----> 7 print(division(10, 0))<ipython-input-17-26bfa63ae44c> in division(numerador, denominador)1 def division(numerador, denominador):2 if denominador == 0:----> 3 raise TypeError("El denominador no puede ser 0")45 return numerador/denominadorTypeError: El denominador no puede ser 0
13. Palavras-chave ou palavras reservadas
Durante este post, em várias ocasiões, apareceram palavras reservadas de Python ou keywords; estas são uma série de palavras reservadas pelo Python
A seguir, é mostrada uma lista das keywords
InputPythonimport keywordkeyword.kwlistCopied
['False','None','True','and','as','assert','async','await','break','class','continue','def','del','elif','else','except','finally','for','from','global','if','import','in','is','lambda','nonlocal','not','or','pass','raise','return','try','while','with','yield']
14. O ZEN do Python
Ao importar o módulo this, podemos ler o zen do Python, ou seja, sua filosofia ou princípios
InputPythonimport thisCopied
The Zen of Python, by Tim PetersBeautiful is better than ugly.Explicit is better than implicit.Simple is better than complex.Complex is better than complicated.Flat is better than nested.Sparse is better than dense.Readability counts.Special cases aren't special enough to break the rules.Although practicality beats purity.Errors should never pass silently.Unless explicitly silenced.In the face of ambiguity, refuse the temptation to guess.There should be one-- and preferably only one --obvious way to do it.Although that way may not be obvious at first unless you're Dutch.Now is better than never.Although never is often better than *right* now.If the implementation is hard to explain, it's a bad idea.If the implementation is easy to explain, it may be a good idea.Namespaces are one honking great idea -- let's do more of those!