
Passo 1 de 8
Preparar uma chamada sem executar a função
Crie uma versão especializada de uma função existente e diferencie sua criação da execução posterior.
Trilha de aprendizado · Nível 9 · Tutorial 5
Ao concluir, você será capaz de criar versões especializadas de funções existentes, preenchendo antecipadamente parte dos argumentos sem executar a operação original.
Preparar uma chamada sem executar a função
Crie uma versão especializada de uma função existente e diferencie sua criação da execução posterior. 2 min
Completar os argumentos posicionais
Veja como os argumentos guardados por partial ficam no início da chamada e complete os argumentos restantes na ordem correta. 2 min
Predefinir e substituir argumentos nomeados
Configure valores nomeados ao criar um partial e veja como uma chamada posterior pode substituí-los apenas naquele uso. 2 min
Identificar conflitos de associação
Diagnostique chamadas a objetos partial que atribuem dois valores ao mesmo parâmetro e escolha uma forma válida de corrigi-las. 2 min
Entender o que fica armazenado
Veja como referências a objetos mutáveis se comportam quando são antecipadas com functools.partial. 2 min
Usar partial como chave de ordenação
Especialize uma função de chave para que sorted forneça apenas o registro que ainda falta. 2 min
Escolher entre partial e uma função própria
Escolha a adaptação mais clara: somente preencher argumentos ou acrescentar comportamento. 2 min
Aplicar e verificar uma especialização
Crie e verifique localmente uma chave de ordenação especializada com functools.partial. 3 min

Passo 1 de 8
Crie uma versão especializada de uma função existente e diferencie sua criação da execução posterior.
Aplicação parcial cria uma nova função chamável a partir de uma função existente, deixando parte dos argumentos já preparada. A função original não é executada nesse momento: você apenas monta uma versão especializada para usar depois.
Observe a separação entre preparar a chamada e executá-la.

Criar o objeto parcial prepara uma chamada futura; usar parênteses no objeto parcial é o que dispara a função original.
partial pertence à biblioteca padrão e é importado explicitamente de functools.
from functools import partial
def saudar(saudacao, nome):
print(f"{saudacao}, {nome}!")
bom_dia = partial(saudar, "Bom dia")
print("Objeto parcial criado")
bom_dia("Ana")Em partial(saudar, "Bom dia"), passamos a função saudar — sem parênteses — e o valor que ficará preparado. Portanto, essa linha cria bom_dia, mas não entra no corpo de saudar.
Só bom_dia("Ana") chama o objeto parcial e produz Bom dia, Ana!. Neste primeiro contato, foque na sequência: importar → criar → chamar depois.
Dica
Se a função original tem um print, uma alteração em dados ou outro efeito observável, esse efeito só acontece quando você chama o objeto parcial com parênteses.
Considere o código:
from functools import partial
def notificar(tipo, mensagem):
print(f"[{tipo}] {mensagem}")
notificar_erro = partial(notificar, "ERRO")
notificar_erro("Arquivo ausente")Em qual instrução o print dentro de notificar é executado?

Passo 2 de 8
Veja como os argumentos guardados por partial ficam no início da chamada e complete os argumentos restantes na ordem correta.
Ao criar um partial com argumentos posicionais, eles ficam armazenados como o início da futura chamada. Quando você chama o objeto parcial, os novos argumentos posicionais entram depois deles, na mesma ordem.
Imagine a função com três parâmetros. O primeiro já foi preenchido; os dois seguintes serão recebidos ao chamar a especialização.

A chamada posterior completa o final da lista de argumentos; ela não substitui nem reorganiza o prefixo armazenado.
O objeto etiqueta_loja guarda somente o primeiro argumento posicional.
from functools import partial
def criar_etiqueta(origem, produto, lote):
return f"{origem} | {produto} | lote {lote}"
etiqueta_loja = partial(criar_etiqueta, "Loja Centro")
print(etiqueta_loja("Caderno", 42))
print(etiqueta_loja("Caneta", 17))A primeira chamada é equivalente a criar_etiqueta("Loja Centro", "Caderno", 42). A segunda reutiliza o mesmo prefixo e equivale a criar_etiqueta("Loja Centro", "Caneta", 17).
O mesmo objeto parcial pode ser chamado várias vezes, desde que você forneça os argumentos que ainda faltam.
Dica
Para prever uma chamada, escreva primeiro os argumentos que o partial guardou. Em seguida, acrescente os argumentos da chamada atual. Só então associe cada posição aos parâmetros da função.
Considere:gerar = partial(criar_etiqueta, "Norte")gerar("Relatório", 3)
A chamada equivalente à função original é:criar_etiqueta("Norte", ___, ___)

Passo 3 de 8
Configure valores nomeados ao criar um partial e veja como uma chamada posterior pode substituí-los apenas naquele uso.
Além de argumentos posicionais, partial pode receber argumentos nomeados. Eles ficam associados ao objeto chamável criado e serão usados quando você não informar outro valor para aquele mesmo nome na chamada.
O partial mantém a configuração cor="azul". A chamada posterior fornece a mensagem; se também fornecer cor, esse valor vale apenas para aquela execução.

O argumento nomeado armazenado completa a chamada, mas pode ser substituído por outro argumento nomeado na execução.
from functools import partial
def rotulo(mensagem, cor="cinza"):
return f"{cor}: {mensagem}"
rotulo_azul = partial(rotulo, cor="azul")
print(rotulo_azul("Arquivo salvo"))
# azul: Arquivo salvoSe a chamada ao objeto parcial informar novamente um argumento nomeado já predefinido, o valor dessa chamada prevalece. Isso não altera a configuração guardada no objeto parcial: a substituição é pontual.
print(rotulo_azul("Conexão perdida", cor="laranja"))
# laranja: Conexão perdida
print(rotulo_azul("Reconexão concluída"))
# azul: Reconexão concluídaDica
Leia rotulo_azul("...", cor="laranja") como: use a especialização azul, exceto nesta chamada, em que cor será laranja.
Considerando o código anterior, complete o resultado de rotulo_azul("Conexão perdida", cor="laranja"):
____: Conexão perdida
Depois de chamar rotulo_azul("Conexão perdida", cor="laranja"), uma nova chamada a rotulo_azul("Reconexão concluída") usará cor="laranja".

Passo 4 de 8
Diagnostique chamadas a objetos partial que atribuem dois valores ao mesmo parâmetro e escolha uma forma válida de corrigi-las.
Um objeto criado com partial guarda argumentos, mas a associação final só acontece quando você o chama. Se a combinação dos valores guardados e dos novos valores tentar preencher o mesmo parâmetro duas vezes, Python lança TypeError.
Observe como um valor nomeado guardado pode colidir com um valor posicional fornecido depois.

Na chamada final, cada parâmetro da função precisa receber no máximo um valor.
Atenção
partial(registrar, nivel="INFO") é válido. O erro só ocorre se uma chamada posterior também preencher nivel por posição, como em info_evento("login", "DEBUG").
Execute cada chamada separadamente para comparar os casos.
from functools import partial
def registrar(evento, nivel="INFO"):
return f"{nivel}: {evento}"
info_evento = partial(registrar, nivel="INFO")
print(info_evento("login", nivel="DEBUG")) # válido: DEBUG: login
print(info_evento("login", "DEBUG")) # TypeError
Na primeira chamada, nivel="DEBUG" substitui temporariamente o valor nomeado guardado. Na segunda, "DEBUG" ocupa o segundo parâmetro por posição, que corresponde a nivel; ao mesmo tempo, nivel="INFO" já foi guardado. Portanto, nivel recebe dois valores.
Exemplo
evento_login = partial(registrar, "login") guarda evento por posição. A chamada evento_login(evento="logout") falha: evento recebe "login" pela posição guardada e "logout" pelo nome posterior.
Correção: use evento_login(nivel="DEBUG") se quiser apenas completar o outro parâmetro, ou chame registrar(evento="logout") se o evento precisa mudar.
Considere info_evento = partial(registrar, nivel="INFO") e evento_login = partial(registrar, "login"), usando a função registrar(evento, nivel="INFO").
Toque em um item e depois no par correspondente.
A chamada info_evento("login", "DEBUG") gerou TypeError. Qual parâmetro recebeu dois valores? Escreva uma chamada válida que registre "login" no nível "DEBUG" e explique brevemente a mudança.
Escreva pelo menos 40 caracteres (0/40).

Passo 5 de 8
Veja como referências a objetos mutáveis se comportam quando são antecipadas com functools.partial.
Ao criar um partial, os argumentos antecipados são guardados como referências aos objetos recebidos. Se um desses objetos for mutável, como uma lista, alterações feitas nele depois da criação poderão aparecer nas chamadas futuras.
Portanto, antecipar um argumento não cria uma fotografia imutável de seu conteúdo.

A lista é um único objeto compartilhado: tanto o nome externo quanto o partial apontam para ela.
Crie um arquivo Python, execute-o e compare as duas saídas.
from functools import partial
def mostrar(itens, titulo):
return f"{titulo}: {', '.join(itens)}"
frutas = ["maçã", "banana"]
mostrar_frutas = partial(mostrar, frutas)
print(mostrar_frutas("Antes"))
frutas.append("uva")
print(mostrar_frutas("Depois"))Exemplo
Antes: maçã, banana
Depois: maçã, banana, uva
append modifica o mesmo objeto de lista que foi armazenado por mostrar_frutas. Por isso, a segunda chamada enxerga "uva".
Atenção
Não suponha que partial preserve o estado dos argumentos mutáveis no instante da criação. Ele reutiliza a referência que recebeu.
Reatribuição é diferente de mutação. Ao fazer frutas = ["pera"], o nome frutas passa a apontar para outra lista. Mas mostrar_frutas continua com a referência da lista original.
from functools import partial
def mostrar(itens, titulo):
return f"{titulo}: {', '.join(itens)}"
frutas = ["maçã", "banana"]
mostrar_frutas = partial(mostrar, frutas)
frutas = ["pera"]
print(mostrar_frutas("Guardado no partial"))
print(mostrar(frutas, "Nome frutas agora"))Exemplo
Guardado no partial: maçã, banana
Nome frutas agora: pera
A reatribuição não modifica a lista antiga nem substitui o argumento que o partial já guardou.
Considere:
from functools import partial
def total(valores, extra):
return sum(valores) + extra
itens = [2, 3]
com_taxa = partial(total, itens)
itens.append(5)
itens = [100]
print(com_taxa(1))Qual valor será exibido?

Passo 6 de 8
Especialize uma função de chave para que sorted forneça apenas o registro que ainda falta.
Às vezes, a função que produz a chave de ordenação precisa de uma configuração e de um registro. Neste exemplo, chave_por_campo recebe o nome do campo e um dicionário. Porém, sorted(..., key=...) chamará sua chave com apenas um registro por vez.
Use partial para preencher antecipadamente o campo desejado e deixar o parâmetro registro disponível para sorted.

partial fixa a configuração; sorted entrega cada registro à função especializada.
Crie a especialização sem usar parênteses depois de por_prioridade ao passá-la para key.
from functools import partial
def chave_por_campo(campo, registro):
return registro[campo]
chamados = [
{"titulo": "Revisar relatório", "prioridade": 2},
{"titulo": "Corrigir erro", "prioridade": 1},
{"titulo": "Atualizar guia", "prioridade": 3},
]
por_prioridade = partial(chave_por_campo, "prioridade")
ordenados = sorted(chamados, key=por_prioridade)
print([chamado["titulo"] for chamado in ordenados])
# ['Corrigir erro', 'Revisar relatório', 'Atualizar guia']Dica
key=por_prioridade passa o objeto chamável para sorted. Durante a ordenação, sorted chama algo equivalente a por_prioridade(registro) para cada dicionário.
Complete a criação para ordenar os produtos pelo campo "nome":
por_nome = _____(chave_por_campo, "nome")
Considere produtos = [{"nome": "Caio"}, {"nome": "Ana"}, {"nome": "Bia"}] e por_nome = partial(chave_por_campo, "nome").
Qual será a ordem dos nomes em sorted(produtos, key=por_nome)? Explique qual argumento sorted fornece a por_nome.
Escreva pelo menos 50 caracteres (0/50).

Passo 7 de 8
Escolha a adaptação mais clara: somente preencher argumentos ou acrescentar comportamento.
Use partial quando a especialização apenas fixa argumentos de uma função que já faz exatamente o trabalho necessário. O objeto resultante continua esperando somente os argumentos que faltaram.
Crie uma função própria quando a adaptação precisar fazer algo além de encaminhar argumentos: validar uma entrada, transformar um valor, tomar uma decisão ou combinar mais de uma operação.
Compare o caminho direto de partial com uma função que adiciona uma etapa antes de chamar a operação-base.

partial fixa argumentos; uma função própria comporta lógica adicional.
Exemplo
from functools import partial
def formatar_preco(valor, moeda):
return f"{moeda} {valor:.2f}"
formatar_em_real = partial(formatar_preco, moeda="R$")
print(formatar_em_real(19.9)) # R$ 19.90formatar_em_real apenas fornece moeda="R$". Não há regra nova: partial deixa isso explícito.
Exemplo
def formatar_preco(valor, moeda):
return f"{moeda} {valor:.2f}"
def formatar_preco_promocional(valor):
if valor < 0:
raise ValueError("O preço não pode ser negativo")
valor_com_desconto = valor * 0.9
return formatar_preco(valor_com_desconto, moeda="R$")Aqui há validação e cálculo de desconto. Uma função nomeada expõe esse comportamento e dá um nome útil à regra de negócio.
Dica
Não escolha pelo número de linhas. Escolha pelo contrato: se a nova chamada só completa argumentos, partial costuma ser direto. Se ela adiciona uma regra própria, dê um nome a essa regra em uma função.
Associe cada cenário à solução mais clara.
Toque em um item e depois no par correspondente.
Uma função deve receber uma pontuação, limitar qualquer valor acima de 100 a 100 e então chamar registrar_resultado(pontuacao, categoria="simulado"). Qual opção é mais clara?

Passo 8 de 8
Crie e verifique localmente uma chave de ordenação especializada com functools.partial.
Nesta aplicação, a função-base recebe primeiro o campo e depois o registro. Ao criar partial(chave, "nome"), o campo fica preenchido e sobra apenas o registro — exatamente o argumento que sorted(..., key=...) fornece para cada item.
Argumentos nomeados armazenados podem ser substituídos em uma chamada isolada. Já misturar um valor posicional já armazenado com outro valor nomeado para o mesmo parâmetro produz TypeError na hora da chamada.

O objeto parcial guarda o campo como prefixo posicional; sorted entrega um registro por vez ao parâmetro que sobrou.
Crie um arquivo chamado ordenar_registros.py, copie o script completo abaixo e execute python ordenar_registros.py no terminal. Os asserts não exibem nada quando passam; ao final, o script imprime a lista ordenada e confirma que o conflito foi observado.
from functools import partial
def chave(campo, registro, maiusculas=False):
valor = registro[campo]
return valor.upper() if maiusculas else valor
registros = [
{"nome": "Carlos", "cidade": "Salvador"},
{"nome": "Ana", "cidade": "Recife"},
{"nome": "Beatriz", "cidade": "Manaus"},
]
# "nome" fica armazenado como o primeiro argumento posicional.
por_nome = partial(chave, "nome")
ordenados = sorted(registros, key=por_nome)
assert [registro["nome"] for registro in ordenados] == [
"Ana",
"Beatriz",
"Carlos",
]
# O argumento nomeado posterior substitui apenas nesta chamada.
por_nome_normalizado = partial(chave, "nome", maiusculas=False)
assert por_nome_normalizado(registros[1], maiusculas=True) == "ANA"
assert por_nome_normalizado(registros[1]) == "Ana"
# O campo já foi fornecido por posição em por_nome.
# Fornecê-lo novamente por nome causa conflito na chamada.
conflito_observado = False
try:
por_nome(registros[0], campo="cidade")
except TypeError:
conflito_observado = True
assert conflito_observado
print([registro["nome"] for registro in ordenados])
print("Ordenação verificada e conflito TypeError observado.")Depois de executar o script, relate: a ordem impressa, o que aconteceu com a substituição de maiusculas, por que houve TypeError e por que partial é adequado aqui. Diga também um caso em que você escreveria uma função própria.
Escreva pelo menos 120 caracteres (0/120).
Resumo
partial(funcao, ...) cria um objeto chamável e não executa a função-base durante sua criação.TypeError, mesmo que o objeto parcial tenha sido criado sem erro.partial guarda referências aos objetos recebidos: alterar um objeto mutável pode afetar chamadas futuras; reatribuir apenas o nome externo não troca a referência guardada.partial quando a adaptação for só preencher argumentos. Prefira uma função própria quando precisar validar, transformar valores, decidir caminhos ou combinar operações.Parabéns! Você concluiu: Especializar funções com functools.partial
20 XP
Milhares de cursos online em vídeo, ebooks e áudiobooks.
Para testar seus conhecimentos no decorrer dos cursos online
Gerado diretamente na galeria de fotos do seu celular e enviado ao seu e-mail
Baixe nosso aplicativo pelo QR Code ou pelos links abaixo:.
+ de 10 milhões
de alunos
Certificado grátis e
válido em todo o Brasil
60 mil exercícios
gratuitos
4,8/5 classificação
nas lojas de apps
Cursos gratuitos em
vídeo, ebooks e audiobooks