Encapsular significa “esconder” a implementação de um bloco de código dentro de uma caixa‑preta. Em Python isso é feito com def. Quando chamamos a função, apenas os argumentos e o valor retornado são visíveis ao código que a invoca.
Ao colocar um trecho usado várias vezes dentro de uma função, evitamos duplicação. Exemplo clássico:
def jump(t, x, y):
t.penup()
t.goto(x, y)
t.pendown()
Qualquer parte do programa que precise “pular” a tartaruga pode chamar jump em vez de repetir as três linhas.
Dividir um problema grande em funções menores permite desenvolver, testar e depurar cada parte isoladamente. No exemplo da carinha sorridente, jump e emoticon são módulos independentes.
O código que usa jump não precisa saber que a tartaruga é levantada e depois recolocada; só precisa saber que o salto ocorre. Se a implementação mudar (por exemplo, usar t.setpos), emoticon continua funcionando.
Variáveis criadas dentro de uma função são locais ao seu namespace de chamada. Elas desaparecem ao final da execução e não interferem em variáveis de mesmo nome fora da função.
def double(y):
x = 2
print(f"x = {x}, y = {y}")
return x*y
Após double(3), x e y não existem no shell.
Cada chamada cria um novo namespace. O interpretador procura nomes primeiro no namespace da chamada, depois no global e, por fim, no built‑ins.
Variáveis definidas fora de funções (no módulo ou no shell) são globais. Dentro de funções são locais. O Python decide a origem de um nome na ordem: local → global → built‑ins.
a = 0 # global no shell
def f(b):
a = 6 # local a, não afeta o global
globaldef f(b):
global a
a = 6 # altera o a global
Quando ocorre um erro, o fluxo “normal” é interrompido e o interpretador cria um objeto de exceção. Se não houver try/except, o manipulador padrão exibe o traceback e encerra o programa.
try:
idade = int(input("Idade: "))
print(f"Você tem {idade} anos.")
except ValueError:
print("Use apenas dígitos de 0‑9.")
Se o usuário digitar “quinze”, a exceção ValueError é capturada e o programa continua.
excepttry:
f = open(nome)
except IOError:
print("Erro de I/O")
except ValueError:
print("Valor inválido")
except:
print("Outro erro")
Um módulo é um arquivo .py. Quando importado, o Python cria um namespace cujo nome é o do módulo. Todos os objetos definidos no nível superior (funções, classes, variáveis) tornam‑se atributos desse namespace.
import math
print(math.pi) # math é o namespace do módulo
O interpretador procura o módulo em sys.path. Se o diretório que contém o arquivo não estiver na lista, a importação falha.
__name__Quando o módulo é executado como programa principal, __name__ == '__main__'. Isso permite código de teste:
if __name__ == '__main__':
teste()
Uma classe também possui seu próprio namespace. Os métodos são funções armazenadas nesse namespace. Quando chamamos obj.metodo(), o interpretador traduz para Classe.metodo(obj).
lst = [5,2,8]
lst.sort() # equivale a list.sort(lst)
Portanto, o primeiro parâmetro de todo método é a própria instância (self).
global permite modificar variáveis globais dentro de funções.try/except captura exceções e permite tratamento customizado.except para tipos diferentes.dir() e atributos __name__, __file__, __doc__ ajudam a inspeção.sys.path.if __name__ == '__main__' permite código de teste.self).def f(y):
x = 2
print(f"x={x}, y={y}")
g(3)
def g(y):
x = 4
print(f"x={x}, y={y}")
Qual será a saída ao executar f(1)?
Resposta correta: A) x=2, y=1
x=4, y=3
Explicação: f tem seu próprio namespace (x=2, y=1). Dentro de f chama g(3), que cria outro namespace (x=4, y=3).
Resposta correta: C) Local → Global → Built‑ins
O interpretador procura primeiro no namespace local da chamada, depois no global (módulo) e, por fim, nos built‑ins.
example.py abaixo:
# example.py
def f():
print('f')
def g():
print('g')
x = 10
Se o módulo for importado com from example import *, qual será o conteúdo de dir() no módulo chamador?
Resposta correta: A) ['f', 'g', 'x']
O wildcard importa todos os nomes que não começam com “_”. Assim, f, g e x ficam no namespace do chamador.
def safe_open(nome, modo):
try:
arq = open(nome, modo)
return arq
except:
return None
f = safe_open('inexistente.txt', 'r')
if f is None:
print('Falha ao abrir')
else:
print('Arquivo aberto')
Qual é o comportamento correto desse código quando o arquivo não existe?
Resposta correta: B) Imprime “Falha ao abrir”.
Quando open falha, a exceção é capturada, safe_open devolve None e o if imprime a mensagem.