Não explica a fundo — lista o que você tem que saber

Python Essencial

Um checklist dos fundamentos de Python moderno (3.10+): cada tópico em poucas linhas, com o snippet mínimo e as armadilhas. Se ao ler algo você sentir que não domina, o ponteiro → aprofunde em… indica a apostila completa. Serve de revisão pré-entrevista, de mapa para quem está começando, e de referência rápida no dia a dia.

10 seções + recaptipos · escopo · funções · classesarmadilhas destacadasauto-checagem por seçãocross-references
COMO USAR

O formato "Essencial"

Uma apostila-checklist: densa, sem rodeios, feita para ser varrida — não lida linha a linha.

01

Tipos, valores e igualdade

Dinamicamente tipado (o valor tem tipo, não a variável), fortemente tipado (sem coerção maluca). → aprofunde em Python

TipoMutável?Notas
intnãoprecisão arbitrária (sem overflow)
floatnão0.1 + 0.2 != 0.3; math.isclose para comparar
strnãoUnicode; f-string f"{x}"
boolnãosubclasse de int: True == 1
Noneo "nada" (equivale a null); teste com is None
list, dict, setsimseção 03
tuple, frozenset, bytesnãohasháveis (podem ser chave de dict)
type(x)                 # o tipo
isinstance(x, (int, float))   # checagem (aceita tupla de tipos)
x == y                  # igualdade de VALOR
x is y                  # mesma IDENTIDADE (mesmo objeto na memória)
x is None               # SEMPRE assim para None (nunca == None)

Truthiness

Falsy: False, None, 0, 0.0, "", [], {}, (), set(), e objetos com __len__() == 0. Todo o resto é truthy.

⚠️ Armadilhas
  • is vs ==: is só para None (e sentinelas). a is b pode dar True para inteiros pequenos e strings curtas (cache do CPython) — não confie nisso.
  • if x: quando x pode ser 0 ou "" válido → use if x is not None:.
  • "3" + 3TypeError (não coage). int("3") + 3.
  • Strings e tuplas são imutáveis: "modificar" cria um objeto novo.
✔️ Auto-checagem

Diferença entre is e ==, e quando usar cada. Por que x == None é errado. Quais tipos são imutáveis. O que é falsy em Python. Por que True + True == 2.

02

Nomes, escopo e "tudo é objeto"

Variável = um nome ligado a um objeto. Atribuição nunca copia — só religa o nome. → aprofunde em Python

a = [1, 2, 3]
b = a           # b e a apontam para a MESMA lista
b.append(4)     # a agora é [1, 2, 3, 4]  ← aliasing
c = a[:]        # cópia RASA (ou list(a), a.copy())
import copy; d = copy.deepcopy(a)   # cópia PROFUNDA

Escopo: LEGB

Ao ler um nome, Python procura em: Local → Enclosing (função externa) → Global (módulo) → Built-in.

x = 10
def f():
    global x        # para ATRIBUIR a x global de dentro da função
    x = 20
def outer():
    y = 1
    def inner():
        nonlocal y   # para atribuir ao y do enclosing
        y += 1
⚠️ Armadilhas
  • Argumento default mutável: def f(x=[]): — a lista é criada uma vez e reusada entre chamadas. Use def f(x=None): x = x or [].
  • Passar uma lista/dict para uma função e mutá-la lá dentro afeta o chamador (passagem por referência do objeto).
  • Atribuir a um nome dentro da função o torna local — ler antes de atribuir dá UnboundLocalError (a menos de global/nonlocal).
  • Loop variable "vaza" para fora do for (não tem escopo de bloco).
✔️ Auto-checagem

O que é LEGB? Por que def f(x=[]) é uma armadilha e como corrigir? Diferença entre b = a e b = a[:] numa lista. Quando usar global / nonlocal?

03

Estruturas de dados

list / tuple / dict / set + comprehensions + slicing. → aprofunde em Python · Algoritmos com Python (complexidade)

SintaxeUsoChave/valor
list[1, 2, 3]sequência ordenada, mutávelíndice; append, pop, sort
tuple(1, 2) / 1, 2sequência imutável; retorno múltiploíndice; hasheável
dict{"a": 1}mapa hash, ordem de inserção (3.7+)d["a"], d.get("a", pad), .items()/.keys()/.values()
set{1, 2, 3}únicos, operações de conjunto (& | - ^)in é O(1)
# comprehensions
[x*x for x in nums if x % 2 == 0]        # list
{k: v for k, v in pares}                  # dict
{x % 3 for x in nums}                       # set
(x for x in nums)                          # generator (lazy, não é tuple comprehension)

# slicing (funciona em list, str, tuple)
a[1:4]     a[::2]     a[::-1]     a[:-1]        # start:stop:step

# unpacking
primeiro, *meio, ultimo = [1, 2, 3, 4, 5]      # meio = [2, 3, 4]
d = {**d1, **d2}                               # merge de dicts (d2 vence)
f(*args, **kwargs)                             # espalhar em chamada

# idiomas úteis
from collections import Counter, defaultdict, deque
Counter(lista).most_common(3)
d = defaultdict(list); d[k].append(v)          # sem checar se a chave existe
⚠️ Armadilhas
  • list.sort() muta e retorna None; sorted(list) retorna nova lista. Idem reverse() vs reversed().
  • d[chave] lança KeyError se ausente; d.get(chave) retorna None. Use get ou defaultdict.
  • [[0]*3]*3 cria 3 referências para a mesma linha. Use [[0]*3 for _ in range(3)].
  • x in lista é O(n); x in set/x in dict é O(1). Para muitas checagens, use set.
  • Modificar uma lista enquanto itera sobre ela → comportamento errático. Itere sobre uma cópia (for x in lista[:]) ou construa uma nova.
✔️ Auto-checagem

Diferença entre sort e sorted. Como inverter uma lista/string com slicing. Por que [[0]*3]*3 é uma cilada. Quando set em vez de list. Escreva um dict comprehension que inverte chave↔valor.

04

Controle de fluxo

Indentação é a sintaxe (4 espaços). → aprofunde em Python

if cond:
    ...
elif outra:
    ...
else:
    ...

for i, item in enumerate(lista, start=1):   # índice + valor
    ...
for a, b in zip(xs, ys):                    # iterar em paralelo (para no menor)
    ...
for x in lista:
    if achou: break
else:                                       # roda se o for NÃO deu break
    print("não achou")

while cond:
    ...
    if pular: continue

# match (3.10+) — pattern matching, não é só switch
match ponto:
    case (0, 0):            print("origem")
    case (x, 0) | (0, x):   print("eixo")
    case (x, y) if x == y: print("diagonal")
    case _:                print("outro")

# walrus := — atribui e usa na mesma expressão
while (linha := f.readline()):
    processar(linha)
⚠️ Armadilhas
  • Não existe i++ nem ++i; é i += 1.
  • range(n) vai de 0 a n-1. range(a, b, passo).
  • Ternário é a if cond else b (ordem diferente de outras linguagens).
  • Misturar tabs e espaços → TabError. Configure o editor para 4 espaços.
  • Encadear comparações funciona: 0 < x < 10 é válido e legível.
✔️ Auto-checagem

O que for...else faz? Diferença entre enumerate e zip. O que o walrus := resolve? Um match não é só um switch — por quê?

05

Funções

Funções são objetos (podem ser passadas, retornadas, atribuídas). → aprofunde em Python

def f(a, b, /, c, *args, d=10, **kwargs) -> int:
    """docstring."""
    return a + b
# a, b  → positional-only (antes do /)
# c     → posicional ou nomeado
# *args → tupla dos posicionais extras
# d     → keyword-only (depois de *), com default
# **kwargs → dict dos nomeados extras

quadrado = lambda x: x*x            # expressão anônima, uma linha só

# type hints (não são checados em runtime; use mypy/pyright)
def saudar(nome: str, vezes: int = 1) -> str: ...
from typing import Optional        # ou str | None no 3.10+

Decorators (noção)

@cache                              # functools.cache — memoiza
def fib(n): ...

# um decorator é uma função que recebe uma função e retorna outra
def logar(fn):
    def wrapper(*a, **kw):
        print("chamando", fn.__name__)
        return fn(*a, **kw)
    return wrapper
⚠️ Armadilhas
  • Default mutável (seção 02): def f(x=[]) — nunca.
  • *args/**kwargs na definição empacotam; na chamada desempacotam.
  • Type hints não impedem nada em runtime — são para o leitor e o checker.
  • Lambda só para expressões triviais; se precisa de if/statements, use def.
  • Toda função retorna algo: sem return, retorna None.
✔️ Auto-checagem

O que *args e **kwargs fazem na definição vs na chamada? O que / e * na assinatura significam? O que é um decorator, em uma frase? Type hints são checados em runtime?

06

Classes

self explícito. Sem private de verdade (convenção _x). → aprofunde em Python

class Conta:
    taxa = 0.02                     # atributo de CLASSE (compartilhado)

    def __init__(self, saldo=0):
        self.saldo = saldo          # atributo de INSTÂNCIA
        self._historico = []        # _ = "não mexa" (convenção)

    def depositar(self, v):
        self.saldo += v

    @property
    def disponivel(self):           # acessa como atributo: c.disponivel
        return self.saldo * (1 - Conta.taxa)

    @staticmethod
    def valida(v): return v > 0     # sem self nem cls

    @classmethod
    def nova(cls): return cls(100)   // factory; cls = a classe

    def __repr__(self):             # o que aparece no debugger/repl
        return f"Conta(saldo={self.saldo})"

class Poupanca(Conta):
    def __init__(self, saldo=0, rendimento=0.01):
        super().__init__(saldo)
        self.rendimento = rendimento

Dataclass (para "sacos de dados")

from dataclasses import dataclass
@dataclass
class Ponto:
    x: int
    y: int = 0            # gera __init__, __repr__, __eq__ de graça
⚠️ Armadilhas
  • Esquecer self no 1º parâmetro dos métodos.
  • Atributo de classe mutável (historico = [] no corpo da classe) é compartilhado entre todas as instâncias — coloque no __init__.
  • _x é convenção; __x faz name-mangling (vira _Classe__x) — não é privacidade real.
  • Herança múltipla existe e segue a MRO (Classe.__mro__); use com muita parcimônia. Prefira composição.
  • Sem __repr__, o objeto imprime como <Conta object at 0x...> — inútil para debug.
✔️ Auto-checagem

Diferença entre atributo de classe e de instância (e a armadilha do mutável). Quando @staticmethod vs @classmethod? O que @property faz? Para que serve __repr__? Quando usar @dataclass?

07

Erros, exceções e with

EAFP: "peça perdão, não permissão" — tente e trate a exceção, em vez de checar tudo antes. → aprofunde em Python · FastAPI

try:
    v = d[chave]
except KeyError:
    v = padrao
except (ValueError, TypeError) as e:
    log.error("falha: %s", e)
    raise                       # re-lança o mesmo
else:
    # roda se o try NÃO lançou
finally:
    # SEMPRE roda (cleanup)

raise ValueError("mensagem")
raise RuntimeError("contexto") from e     # encadeia a causa

class ValidacaoError(Exception):            # exceção custom: herde de Exception
    pass

Hierarquia (o que você trata)

BaseExceptionException → (ValueError, TypeError, KeyError, IndexError, FileNotFoundError, AttributeError, StopIteration, RuntimeError, …). Capture Exception no máximo — nunca except: pelado (pega KeyboardInterrupt, SystemExit).

with — context managers

with open("dados.txt") as f:      # fecha o arquivo mesmo se der erro
    conteudo = f.read()
with lock, open(a) as fa, open(b) as fb:   # vários
    ...
⚠️ Armadilhas
  • except Exception: silencioso (sem log, sem re-raise) = engolir bug.
  • except: pelado ou except BaseException: — captura Ctrl+C e saída do sistema.
  • Não use exceção para fluxo esperado a ponto de esconder a lógica; mas EAFP idiomático (tentar o d[k] e tratar KeyError) é ok.
  • Abrir arquivo/conexão sem with → vaza recurso se der erro no meio.
  • raise sozinho dentro do except re-lança preservando o traceback; raise NovaEx() from e encadeia.
✔️ Auto-checagem

Quando else e finally num try rodam? Por que nunca except: pelado? O que o with garante? EAFP vs LBYL. Como re-lançar sem perder o traceback?

08

Módulos, pacotes e ambientes

Um arquivo .py = um módulo. Uma pasta com módulos = um pacote. → aprofunde em Python · Git & GitHub · DevOps/Docker

import json
import numpy as np
from pathlib import Path
from mypkg.util import helper
from . import irmao          # import relativo (dentro de um pacote)

if __name__ == "__main__":      # só roda quando o arquivo é executado direto,
    main()                       # não quando é importado

Ambiente e dependências

PassoComando
Criar ambiente isoladopython -m venv .venv · source .venv/bin/activate (ou uv venv)
Instalarpip install requests · pip install -r requirements.txt · uv pip install ...
Congelarpip freeze > requirements.txt (ou pyproject.toml + lock com uv/Poetry)
Rodarpython -m meu_modulo · python script.py

Nunca instale pacotes no Python do sistema. Sempre um venv por projeto. uv é o gerenciador moderno (rápido; substitui pip/venv/pip-tools).

⚠️ Armadilhas
  • Esquecer o if __name__ == "__main__": → o código roda ao importar o módulo em outro lugar (e em testes).
  • Import circular (A importa B que importa A) → ImportError ou nome incompleto. Reorganize.
  • from modulo import * polui o namespace — evite.
  • Rodar sem ativar o venv → usa pacotes errados / do sistema.
  • Nome de arquivo igual a um módulo da stdlib (random.py, json.py) → sombreia a stdlib.
✔️ Auto-checagem

Para que serve if __name__ == "__main__":? Por que um venv por projeto? Diferença entre import x e from x import y. O que quebra num import circular?

09

Iteração e código "pythonic"

Iterar sobre o objeto, não sobre índices. Preferir comprehension a loop que só constrói lista. → aprofunde em Python · Análise de Dados com Python

Iterável vs iterador vs generator

def pares_ate(n):
    for i in range(0, n, 2):
        yield i               # pausa aqui, devolve i, retoma na próxima

for x in pares_ate(1_000_000):   # não cria 1M de itens na memória
    ...

# generator expression: some sem construir a lista
total = sum(x*x for x in nums)

Idiomas que sinalizam fluência

Em vez de…Faça
for i in range(len(lista)):for item in lista: ou for i, item in enumerate(lista):
construir lista num loop e retornarcomprehension (ou generator se só vai iterar)
if lista != []:if lista:
concatenar string com += num loop"".join(partes)
d.keys() só para inif k in d:
abrir/fechar arquivo na mãowith open(...) as f:
a, b = b, a via tempa, b = b, a (swap direto)
ler o "Zen"import this — "explícito > implícito", "simples > complexo", "legibilidade conta"

Bibliotecas para conhecer: itertools (chain, groupby, product, islice), functools (cache, reduce, partial), collections (Counter, defaultdict, deque, namedtuple).

⚠️ Armadilhas
  • Um generator esgota: depois de iterar uma vez, está vazio. list(gen) para materializar.
  • zip para no menor iterável (use itertools.zip_longest se precisar do maior).
  • Comprehension aninhada difícil de ler = use um loop normal.
  • range, map, filter, dict.items() são lazy — não são listas; embrulhe com list() se precisar reusar.
✔️ Auto-checagem

Diferença entre iterável, iterador e generator. O que yield faz? Por que sum(x for x in ...) é melhor que sum([x for x in ...])? Reescreva um for i in range(len(...)) de forma pythonic. O que zip faz quando os iteráveis têm tamanhos diferentes?

10

O resto do essencial

Itens que caem e você tem que reconhecer. → aprofunde em Python · Análise de Dados com Python · FastAPI

TópicoO mínimo
f-stringsf"{x:.2f}", f"{x:,}" (milhar), f"{x=}" (debug: imprime x=valor), f"{dt:%Y-%m-%d}"
pathlibPath("dir") / "arquivo.txt", .exists(), .read_text(), .glob("*.csv"). Prefira a os.path
jsonjson.loads(s) / json.dumps(o, indent=2, ensure_ascii=False). Não serializa datetime/set sem default=
datetimedatetime.now(tz=...) — sempre com timezone; date, timedelta. Formatar: strftime; parsear: strptime / fromisoformat
logginglogging.getLogger(__name__) + logger.info("...", extra=...). Nunca print para diagnóstico em código real
typinglist[int], dict[str, int], X | None (3.10+), Optional, Any, Callable`, TypedDict, Protocol. Checar com mypy/pyright
Números1_000_000 (separador), // (divisão inteira), %, **, divmod, round (banker's rounding), decimal.Decimal para dinheiro
Strings.strip(), .split(), .join(), .replace(), .startswith/endswith, .lower/upper, in. str é imutável
Mutabilidade & aliasingPassar list/dict a função e mutá-la afeta o chamador. Copie (.copy(), [:], deepcopy) quando não quer isso
Comprehension vs loopComprehension para transformar/filtrar; loop quando há efeito colateral ou lógica complexa
GIL (1 frase)Só uma thread executa bytecode Python por vez → threads ajudam em I/O, não em CPU. Para CPU: multiprocessing, concurrent.futures.ProcessPoolExecutor, ou libs em C/Rust
async (noção)async def / await / asyncio.run(main()) / asyncio.gather(...) — concorrência de I/O, single-thread. → FastAPI
Testespytest: def test_x(): assert f(2) == 4. Rodar pytest -q
EstiloPEP 8; formatadores/linters: ruff (o padrão moderno) / black
✔️ Auto-checagem

O que f"{x=}" imprime? / vs //. Por que print não substitui logging? O que o GIL implica para threads? Como copiar um dict aninhado sem aliasing? O que é PEP 8 e qual ferramenta aplica?

RECAP

Checklist final dos fundamentos de Python

Se você marca todos de cabeça, tem o básico. Onde travar, volte à seção — e à apostila completa se a dúvida for de fundo.

✅ Eu sei…
  • quais tipos são imutáveis; por que is None e nunca == None
  • a diferença entre is e == (e por que não confiar em is para inteiros/strings)
  • o que é falsy em Python e por que if x: pode ser bug com 0/""
  • que variável é um nome, que b = a não copia, e como copiar (raso vs deepcopy)
  • a regra LEGB, global, nonlocal, e a armadilha do default mutável
  • list / tuple / dict / set — quando cada um, e que in em set/dict é O(1)
  • comprehensions (list/dict/set) e generator expressions
  • slicing (a[::-1], a[1:4]), unpacking (a, *rest = ..., {**d1, **d2})
  • que sort() muta e retorna None; sorted() retorna nova lista
  • a cilada do [[0]*3]*3
  • for...else, enumerate, zip, match (3.10+), walrus :=
  • *args/**kwargs (definição empacota, chamada desempacota), / e * na assinatura
  • type hints (não são runtime), lambda, e o que é um decorator
  • self; atributo de classe vs instância (e a armadilha do mutável)
  • @property, @staticmethod, @classmethod, __repr__, @dataclass
  • try/except/else/finally, raise ... from e, exceção custom
  • nunca except: pelado; nunca engolir erro sem log/re-raise
  • with para arquivos/locks/conexões; EAFP
  • if __name__ == "__main__":; um venv por projeto; uv/pip
  • iterável vs iterador vs generator; yield; idiomas pythonic (iterar sobre o objeto, "".join, if lista:)
  • o GIL em uma frase; logging em vez de print; pathlib; ruff/PEP 8

Aprofundamento por tema: Python (do básico ao avançado, a apostila completa) · Análise de Dados com Python (pandas, numpy) · Algoritmos com Python (estruturas e complexidade) · FastAPI (async, APIs) · Aceleração de Código com IA (fluxo assistido).