Questão por questão: o código, a saída real e por que a resposta certa é certa. Aulas 01–12.
Questão 1 · Representação de objetos
O que o programa imprime?
class Ponto:
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
return f"({self.x}, {self.y})"
p = Ponto(2, 5)
print(p) # (2, 5)
print(f"Ponto em {p}") # Ponto em (2, 5) __str__ devolve a string usada tanto por print(p) quanto pela f-string. Sem ele, as duas linhas mostrariam algo como <__main__.Ponto object at 0x...>.Questão 2 · Parâmetro padrão mutável
Qual a saída, na ordem?
def add(item, lista=[]):
lista.append(item)
return lista
print(add(1)) # [1]
print(add(2)) # [1, 2] [] é avaliado uma única vez, na definição da função, e reaproveitado entre as chamadas — por isso o segundo add acumula.Questão 3 · Classes abstratas (asserção-razão)
Avalie as asserções I e II e a relação entre elas.
from abc import ABC, abstractmethod
class Pagamento(ABC):
@abstractmethod
def processar(self, valor): ...
class Pix(Pagamento):
def processar(self, valor):
return f"Pix de R$ {valor}"
print(Pix().processar(50)) # Pix de R$ 50
# Pagamento()
# TypeError: Can't instantiate abstract class Pagamento
# without an implementation for abstract method 'processar' Pagamento tem método abstrato, então é abstrata e não instancia; Pix implementa processar(), virando concreta e instanciável.Questão 4 · Encapsulamento com validação
O que acontece na execução?
class Termostato:
def __init__(self):
self._temp = 20
@property
def temp(self):
return self._temp
@temp.setter
def temp(self, valor):
if valor < 10 or valor > 30:
raise ValueError("Fora da faixa")
self._temp = valor
t = Termostato()
t.temp = 25
print(t.temp) # 25
t.temp = 40 # ValueError: Fora da faixa
print("fim") # não chega a executar temp = 25 passa e imprime 25. temp = 40 dispara o ValueError no setter; como não há try/except, o programa para ali e a linha do "fim" não roda.Questão 5 · try / except / else / finally
Qual a saída, na ordem?
def dividir(a, b):
return a / b
try:
r = dividir(10, 0)
except ZeroDivisionError:
print("erro") # roda: houve exceção
else:
print("ok") # NÃO roda: else é só quando não há exceção
finally:
print("fim") # sempre roda
# Saída: erro / fim dividir(10, 0) levanta ZeroDivisionError → o except imprime "erro". O else só roda quando não há exceção, então é pulado. O finally roda sempre. Saída: erro, depois fim.Questão 6 · Herança e sobrescrita
O que o programa imprime?
class Animal:
def __init__(self, nome):
self.nome = nome
def falar(self):
return "..."
class Cao(Animal):
def falar(self):
return "Au"
c = Cao("Rex")
print(c.nome, c.falar()) # Rex Au Cao não define __init__, então herda o de Animal (que cria self.nome) → "Rex". E falar() é sobrescrito na subclasse → "Au".Questão 7 · property + setter (clamp)
Qual a saída, na ordem?
class Avaliacao:
def __init__(self):
self._nota = 0
@property
def nota(self):
return self._nota
@nota.setter
def nota(self, valor):
self._nota = max(0, min(10, valor))
a = Avaliacao()
a.nota = 15
print(a.nota) # 10
a.nota = -3
print(a.nota) # 0 min(10, 15) = 10 e max(0, -3) = 0. Não levanta erro — apenas corrige o valor. Saída: 10, depois 0.Questão 8 · Exceção customizada
Qual a saída, na ordem?
class SaldoInsuficienteError(Exception):
def __init__(self, saldo, valor):
self.falta = valor - saldo
super().__init__(f"Faltam R$ {self.falta:.2f}")
def sacar(saldo, valor):
if valor > saldo:
raise SaldoInsuficienteError(saldo, valor)
return saldo - valor
try:
sacar(100, 150)
except SaldoInsuficienteError as e:
print("Erro:", e) # Erro: Faltam R$ 50.00
print("Falta:", e.falta) # Falta: 50 falta = 150 - 100 = 50; o super().__init__ formata a mensagem "Faltam R$ 50.00" (que é o texto da exceção). e.falta guarda o número 50.Questão 9 · Hierarquia de exceções
O que o programa faz?
try:
x = [1, 2, 3][10]
except LookupError:
print("capturado") # capturado [1, 2, 3][10] levanta IndexError, que é subclasse de LookupError. Capturar a mãe pega também as filhas, então o except trata e imprime "capturado".Questão 10 · Polimorfismo (duck typing)
O que o programa imprime?
class Pato:
def som(self):
return "Quack"
class Cao:
def som(self):
return "Au"
def coro(bichos):
return [b.som() for b in bichos]
print(coro([Pato(), Cao()])) # ['Quack', 'Au'] coro só chama .som() em cada objeto — não exige superclasse comum. Como Pato e Cao têm o método, funciona (duck typing). Saída: ['Quack', 'Au'].Prática · Questão 1 · Classe Produto
Classes, property/setter com validação, exceções e __str__.
class Produto:
def __init__(self, nome, preco, quantidade):
self.nome = nome
self.preco = preco # passa pelo setter (valida)
self.quantidade = quantidade # idem
@property
def preco(self):
return self._preco
@preco.setter
def preco(self, valor):
if valor < 0:
raise ValueError("preço não pode ser negativo")
self._preco = valor
@property
def quantidade(self):
return self._quantidade
@quantidade.setter
def quantidade(self, valor):
if valor < 0:
raise ValueError("quantidade não pode ser negativa")
self._quantidade = valor
def valor_em_estoque(self):
return self.preco * self.quantidade
def vender(self, qtd):
if qtd > self.quantidade:
raise ValueError(f"Estoque insuficiente: há {self.quantidade}, pedido {qtd}")
self.quantidade -= qtd
def __str__(self):
return f"{self.nome} — R$ {self.preco:.2f} ({self.quantidade} em estoque)"
# Demonstração
p = Produto("Caneta", 2.50, 15)
print(p) # Caneta — R$ 2.50 (15 em estoque)
print("Valor em estoque:", p.valor_em_estoque()) # Valor em estoque: 37.5
p.vender(5)
print("Após vender 5:", p) # Após vender 5: Caneta — R$ 2.50 (10 em estoque)
try:
p.vender(100)
except ValueError as e:
print("Erro:", e) # Erro: Estoque insuficiente: há 10, pedido 100 preco/quantidade com property + setter rejeitando negativo (ValueError), valor_em_estoque(), vender() com checagem de estoque, e __str__ no formato pedido. O texto exato das mensagens de erro pode variar — o que conta é o comportamento.Prática · Questão 2 · Acervo de biblioteca
Classe abstrata (ABC), herança, exceção customizada e __str__ polimórfico.
from abc import ABC, abstractmethod
class ItemIndisponivelError(Exception):
pass
class ItemAcervo(ABC):
def __init__(self, titulo):
self.titulo = titulo
@abstractmethod
def prazo_dias(self):
...
def __str__(self):
return f"{self.titulo} (empréstimo: {self.prazo_dias()} dias)"
class Livro(ItemAcervo):
def prazo_dias(self):
return 14
class Revista(ItemAcervo):
def prazo_dias(self):
return 7
class Acervo:
def __init__(self):
self.itens = []
def adicionar(self, item):
self.itens.append(item)
def listar(self):
for item in self.itens:
print(item) # polimorfismo: cada item formata seu __str__
def emprestar(self, titulo):
for item in self.itens:
if item.titulo == titulo:
self.itens.remove(item)
return item
raise ItemIndisponivelError(f"Item '{titulo}' não está disponível no acervo")
# Demonstração
acervo = Acervo()
acervo.adicionar(Livro("Python Fluente"))
acervo.adicionar(Revista("Veja"))
print("Acervo:")
acervo.listar() # Python Fluente (empréstimo: 14 dias)
# Veja (empréstimo: 7 dias)
emprestado = acervo.emprestar("Veja")
print("Emprestado:", emprestado) # Emprestado: Veja (empréstimo: 7 dias)
print("Acervo após empréstimo:")
acervo.listar() # Python Fluente (empréstimo: 14 dias)
try:
acervo.emprestar("O Hobbit")
except ItemIndisponivelError as e:
print("Erro:", e) # Erro: Item 'O Hobbit' não está disponível no acervo ItemAcervo abstrata com prazo_dias() abstrato, subclasses Livro/Revista concretas, ItemIndisponivelError customizada, e listar() usando só print(item) — a formatação vem do __str__ (polimorfismo).Resumo
As dez respostas em um lugar. A parte prática é avaliada pela execução correta, não por letra.
__str__
default mutável
classe abstrata
property valida
try/finally
herança
clamp 0–10
exceção custom
LookupError
duck typing