Python 3.14: Template Strings na Prática
Veja como usar template strings do Python 3.14 com exemplos reais, diferenças para f-strings e casos de uso em logs, HTML e DSLs.
O Python 3.14 traz uma novidade que chama atenção de quem acompanha a evolução da linguagem: as template strings, definidas na PEP 750. À primeira vista, elas parecem só mais uma variação das famosas f-strings. Mas a proposta é diferente: em vez de gerar imediatamente uma str, uma template string preserva a estrutura da interpolação para que seu código possa inspecionar, transformar ou serializar cada parte de forma controlada.
Na prática, isso abre espaço para bibliotecas de HTML seguro, logging estruturado, DSLs, geração de consultas e outros fluxos em que você quer manter separadas as partes estáticas do texto e os valores interpolados. Para quem já usa Python em automação, backend ou ferramentas internas, vale entender desde já como esse recurso funciona.
Neste artigo, vamos ver o que são template strings, como elas se diferenciam de f-strings, quais casos de uso fazem sentido e como experimentar a sintaxe do Python 3.14 com exemplos práticos.
O que muda com template strings?
Com uma f-string tradicional, o Python avalia as expressões e produz uma string final:
nome = "Diego"
mensagem = f"Olá, {nome}!"
print(mensagem) # Olá, Diego!
print(type(mensagem)) # <class 'str'>
Com uma template string, usando o prefixo t, o resultado deixa de ser uma str simples. O Python cria um objeto de template que mantém as partes literais e as interpolações separadas:
nome = "Diego"
template = t"Olá, {nome}!"
print(type(template))
# <class 'string.templatelib.Template'>
Segundo a PEP 750, essa estrutura foi criada para custom string processing. Ou seja: a linguagem passa a oferecer uma forma nativa de capturar uma string interpolada sem necessariamente convertê-la para texto final naquele momento.
Esse detalhe parece pequeno, mas muda bastante o jogo. Em vez de perder contexto logo na interpolação, você pode aplicar regras próprias de renderização, escape, validação e serialização depois.
Template string vs f-string
A melhor forma de entender é comparar os dois recursos lado a lado:
| Recurso | f-string | template string |
|---|---|---|
| Prefixo | f"..." | t"..." |
| Resultado | str | Template |
| Interpolação | Avalia e concatena | Avalia e preserva estrutura |
| Casos de uso | Texto final | Processamento customizado |
| Ideal para | Mensagens, labels, logs simples | HTML seguro, DSLs, logging estruturado |
A semelhança sintática é proposital. Você continua escrevendo expressões entre chaves, podendo usar conversões como !r, formatação como :.2f e até a sintaxe de debug =. A diferença é o que acontece depois da avaliação.
Inspecionando as partes do template
Um template pode ser percorrido para acessar segmentos literais e interpolações. Isso é o que permite criar processadores reutilizáveis:
from string.templatelib import Interpolation
produto = "Notebook"
preco = 4299.90
template = t"Produto: {produto} | Preço: R$ {preco:.2f}"
for parte in template:
if isinstance(parte, Interpolation):
print("Expressão:", parte.expression)
print("Valor:", parte.value)
print("Conversão:", parte.conversion)
print("Format spec:", parte.format_spec)
else:
print("Texto literal:", parte)
Esse tipo de introspecção não existe com f-strings comuns. Quando você usa f"...", o Python já devolve o texto pronto. Já na template string, cada interpolação é representada como um objeto com metadados úteis.
Isso lembra um pouco como frameworks modernos tratam ASTs, consultas estruturadas ou builders de HTML. A vantagem é que agora o próprio Python fornece uma sintaxe elegante para capturar esse material.
Exemplo prático: renderização segura para HTML
Um caso de uso clássico é escapar valores interpolados para evitar problemas de HTML injection. Em vez de concatenar strings manualmente, podemos processar o template:
from html import escape
from string.templatelib import Interpolation
def render_html_seguro(template) -> str:
partes = []
for parte in template:
if isinstance(parte, Interpolation):
partes.append(escape(str(parte.value)))
else:
partes.append(parte)
return "".join(partes)
usuario = "<script>alert('xss')</script>"
pagina = t"<p>Bem-vindo, {usuario}!</p>"
html_final = render_html_seguro(pagina)
print(html_final)
# <p>Bem-vindo, <script>alert('xss')</script>!</p>
Se você fizesse isso com f-strings puras, teria de lembrar de escapar cada valor antes da interpolação. Com template strings, a regra fica centralizada em uma função. Esse padrão pode ser útil em ferramentas internas, mini motores de template e integrações web. Se você trabalha com APIs e aplicações web, vale revisar também nosso conteúdo sobre FastAPI e segurança em aplicações Python.
Exemplo prático: logging estruturado
Outro cenário interessante é logging. Em muitos sistemas, queremos guardar não só a mensagem renderizada, mas também os valores originais para indexação, busca ou observabilidade.
from string.templatelib import Interpolation
def log_estruturado(template) -> dict:
mensagem = []
campos = {}
for indice, parte in enumerate(template):
if isinstance(parte, Interpolation):
chave = parte.expression or f"campo_{indice}"
campos[chave] = parte.value
mensagem.append(f"{{{chave}}}")
else:
mensagem.append(parte)
return {
"message_template": "".join(mensagem),
"fields": campos,
}
usuario_id = 42
acao = "checkout"
resultado = log_estruturado(t"Usuário {usuario_id} executou {acao}")
print(resultado)
Saída esperada:
{
'message_template': 'Usuário {usuario_id} executou {acao}',
'fields': {
'usuario_id': 42,
'acao': 'checkout'
}
}
Esse modelo conversa bem com pipelines de observabilidade e sistemas de métricas. Para quem usa Python em backend e automação, pode ser uma alternativa elegante a montar dicionários e mensagens em separado. Se você gosta desse tipo de arquitetura, aproveite para ler também nosso artigo sobre logging em Python.
Exemplo prático: DSL simples para consultas
Template strings também podem servir como base para uma DSL controlada. A ideia não é montar SQL cru sem cuidado, mas demonstrar como separar estrutura e parâmetros:
from string.templatelib import Interpolation
def compilar_consulta(template):
sql = []
parametros = []
for parte in template:
if isinstance(parte, Interpolation):
sql.append("%s")
parametros.append(parte.value)
else:
sql.append(parte)
return "".join(sql), parametros
status = "ativo"
limite = 10
consulta, params = compilar_consulta(
t"SELECT * FROM clientes WHERE status = {status} LIMIT {limite}"
)
print(consulta)
print(params)
Resultado:
SELECT * FROM clientes WHERE status = %s LIMIT %s
['ativo', 10]
Esse padrão ajuda a reforçar a separação entre comando e parâmetros. Em aplicações reais, você continuaria usando o driver ou ORM adequado, como mostramos em conteúdos sobre PostgreSQL com Python e MongoDB com Python.
O que continua igual em relação às f-strings?
Apesar do novo propósito, as template strings reaproveitam boa parte da ergonomia das f-strings. Você ainda pode usar:
- expressões Python entre chaves;
- conversões como
!re!s; - format spec como
:.2f; - formas raw, como
rt"..."etr"..."; - sintaxe de debug com
=.
Exemplo:
valor = 123.456
template = t"Valor formatado: {valor:.1f}"
A interpolação continua sendo avaliada da esquerda para a direita, assim como ocorre com f-strings. Ou seja, template strings não são avaliação preguiçosa das expressões; o que elas adiam é a transformação no texto final.
Limitações e cuidados
Como o recurso ainda é novo no ecossistema, alguns cuidados são importantes:
- Bibliotecas ainda estão se adaptando: não espere integração imediata com todos os frameworks.
- Não é substituição universal de f-strings: para mensagens simples, f-strings continuam mais diretas.
- Exige Python 3.14: se seu ambiente de produção ainda roda 3.12 ou 3.13, o recurso serve mais para exploração e planejamento.
- Não existe conversão padrão única para string: o ponto da feature é justamente deixar a renderização sob controle do desenvolvedor.
Por isso, o melhor jeito de pensar nesse recurso é como uma ferramenta de baixo nível e alto poder, especialmente útil para bibliotecas e camadas de infraestrutura.
Vale a pena aprender agora?
Sim, principalmente se você gosta de acompanhar recursos que podem influenciar o design de bibliotecas Python nos próximos anos. Template strings têm potencial para aparecer em soluções de:
- sanitização de conteúdo;
- renderização segura de HTML e Markdown;
- logging estruturado;
- geração de consultas e comandos;
- DSLs internas;
- ferramentas de automação com saída formatada.
Mesmo que você não use no dia a dia imediatamente, entender a ideia ajuda a enxergar para onde o Python está indo: menos hacks com concatenação, mais estruturas explícitas e reutilizáveis.
Conclusão
As template strings do Python 3.14 mostram que a linguagem continua evoluindo não apenas em performance, mas também em expressividade para bibliotecas e infraestrutura. A sintaxe familiar reduz a curva de aprendizado, enquanto o retorno em forma de Template cria novas possibilidades para processar texto de maneira mais segura e estruturada.
Para quem trabalha com backend, automação e ferramentas internas, esse é o tipo de novidade que pode parecer nichada no começo, mas ganhar tração rapidamente quando surgirem bibliotecas explorando bem a feature.
Se você quer acompanhar outras mudanças recentes do ecossistema, veja também nossos artigos sobre Python 3.13 e o modo free-threaded, tipagem estática com mypy e boas práticas em Python para 2026.
Equipe python.dev.br
Contribuidor do Python Brasil — Aprenda Python em Português