Walrus Operator e novidades do Python 3.8
O Python 3.8 trouxe uma das features mais controversas dos últimos anos: o walrus operator (:=). Além dele, houve melhorias significativas em funções, f-strings e performance. Vamos conhecer tudo.
Walrus Operator (:=)
O operador := (apelidado de “walrus” porque parece uma morsa de lado) permite atribuir e retornar um valor em uma mesma expressão. Ele foi definido na PEP 572.
Onde antes você escrevia:
linha = input("> ")
while linha != "sair":
print(f"Você digitou: {linha}")
linha = input("> ")
Agora pode escrever:
while (linha := input("> ")) != "sair":
print(f"Você digitou: {linha}")
A variável linha é atribuída e comparada na mesma linha.
Usos práticos
Filtrando e processando em list comprehensions:
# Sem walrus: calcula len() duas vezes
nomes = [nome for nome in lista if len(nome) > 5]
print([nome.upper() for nome in nomes])
# Com walrus: calcula len() uma vez
nomes_grandes = [
nome.upper()
for nome in lista
if (tamanho := len(nome)) > 5
]
Evitando cálculo duplicado:
# Sem walrus
resultado = funcao_cara(dados)
if resultado > limite:
print(f"Resultado: {resultado}")
# Com walrus
if (resultado := funcao_cara(dados)) > limite:
print(f"Resultado: {resultado}")
Em loops com condição:
# Ler dados até encontrar vazio
while (dado := ler_proximo()) is not None:
processar(dado)
Em filtros com logging:
erros = [
linha
for linha in log
if (match := regex_erro.search(linha))
]
Quando NÃO usar
Evite o walrus operator quando:
- A expressão é simples demais (
x := 5é desnecessário) - Reduz a legibilidade em vez de aumentar
- O colega que vai manter seu código não vai entender
positional-only parameters
O Python 3.8 permite definir parâmetros que só podem ser passados por posição, usando /:
def calcular(x, y, /, operacao="soma"):
if operacao == "soma":
return x + y
return x * y
# Correto
calcular(3, 4)
calcular(3, 4, operacao="multiplica")
# Erro! Não pode passar por nome
calcular(x=3, y=4) # TypeError
Isso é útil para bibliotecas que querem liberdade para renomear parâmetros sem quebrar código existente.
f em f-strings para debug
Uma pequena melhoria que salva muito tempo:
nome = "Wellington"
idade = 30
# Antes do 3.8
print(f"nome={nome!r}, idade={idade!r}")
# Python 3.8: o = faz o debug automaticamente
print(f"{nome=}, {idade=}")
# Saída: nome='Wellington', idade=30
# Com expressões
lista = [1, 2, 3]
print(f"{len(lista)=}")
# Saída: len(lista)=3
math.prod
Nova função para multiplicar todos os elementos de uma sequência:
import math
numeros = [2, 3, 4, 5]
print(math.prod(numeros)) # 120
# Equivalente a
from functools import reduce
import operator
reduce(operator.mul, numeros)
typing.TypedDict
Para dicionários com estrutura fixa:
from typing import TypedDict
class UsuarioDict(TypedDict):
nome: str
email: str
idade: int
# Type checker verifica os tipos
user: UsuarioDict = {
"nome": "Wellington",
"email": "well@email.com",
"idade": 30,
}
Outras melhorias
statistics.fmean(): média de ponto flutuante, mais rápida quemean()shlex.join(): junta lista de strings em comando de shell seguroimportlib.metadata: acesso a metadados de pacotes instalados- Melhorias no
asyncio:asyncio.run()estável,asyncio.Task.cancel()melhorado
Conclusão
O Python 3.8 é uma release que melhora a ergonomia da linguagem. O walrus operator é controverso, mas quando usado com moderação, elimina código duplicado e torna loops mais limpos. As positional-only parameters e o f"{var=}" são melhorias que todo mundo usa naturalmente.
Se você ainda não atualizou, vale a pena — especialmente pelo f"{var=}" que economiza muito tempo em debug.
Caso eu tenha falado alguma besteira, por favor, agradecerei correções e sugestões.