Como usar f-strings no Python

Cansado de programar?

Conheça a melhor e mais completa formação de Python e Django e sinta-se um programador verdadeiramente competente. Além de Python e Django, você também vai aprender Banco de Dados, SQL, HTML, CSS, Javascript, Bootstrap e muito mais!

Quero aprender Python e Django de Verdade! Quero aprender!
Suporte

Tire suas dúvidas diretamente com o professor

Projetos práticos

Projetos práticos voltados para o mercado de trabalho

Prática profissional

Formação moderna com foco na prática profissional

Download do Artigo

✅ Artigo atualizado em Setembro 2026 Novas seções sobre o f do print(f"..."), formatação de números, moeda em reais, f-string multilinha e com aspas (antes e depois do Python 3.12), erros comuns e 8 exercícios resolvidos.

Resposta rápida

Uma f-string é uma string com f antes das aspas que insere valores direto no texto: o que está entre chaves é avaliado, como em f"Olá, {nome}". Existe desde o Python 3.6 e aceita expressões e formatação, como {valor:.2f} para duas casas decimais.

1
2
3
4
5
6
nome = "Ana"
preco = 1234.5
print(f"Olá, {nome}!")          # Olá, Ana!
print(f"2 + 3 = {2 + 3}")       # 2 + 3 = 5
print(f"R$ {preco:.2f}")        # R$ 1234.50
print(f"{preco=}")              # preco=1234.5

Resumo em 30 segundos:

  • O f (ou F) vem antes das aspas. Sem ele, o Python imprime as chaves literalmente.
  • Dentro das chaves vale qualquer expressão: {idade + 1}, {nome.upper()}, {"sim" if ok else "não"}.
  • Depois de : vem o especificador de formato: :.2f (casas decimais), :, (milhar), :.1% (porcentagem), :>10 (alinhar).
  • {x=} (Python 3.8+) mostra nome e valor, ótimo para debug. Para escrever chaves literais, use {{ e }}.
  • Antes do Python 3.12, não repita dentro das chaves as mesmas aspas que abrem a f-string: use f"{d['chave']}".

Olá Pythonista!

F-strings (Python 3.6+) são uma das formas mais legíveis e performáticas de formatar strings, com sintaxe mais limpa que .format() e %.

O que é uma f-string? Uma f-string (string literal formatada, introduzida na PEP 498 no Python 3.6) é uma string prefixada com a letra f que permite interpolar expressões diretamente entre chaves {}. As expressões são avaliadas em tempo de execução e formatadas via protocolo __format__. Ex.: f"Olá {nome}".

Neste guia, você vai aprender:

  • ✅ Sintaxe básica - f"{variavel}"
  • ✅ Formatação avançada - Largura, alinhamento, precisão
  • ✅ Debug rápido - f"{var=}" (Python 3.8+)
  • ✅ Casos práticos - Logs, SQL, templates

Então faz o cafézinho nosso de cada dia e vamos nessa!

Vá Direto ao Assunto…

Formatação de Strings em Python

Em Python nós não temos muitas formas de formatar strings, graças a um dos Zen’s do Python (não sabe qual? Então já clica aqui pra saber mais).

Antes do Python 3.6, nós tínhamos basicamente duas formas de formatar strings:

  • Utilizando % ou
  • Utilizando str.format(), a partir do Python 3.0.

A partir da versão 3.6 do Python, foi introduzido o conceito de f-strings, que veremos AGORA!

Formatação com f-strings

F-strings foram criados para facilitar nossa vida e vieram para ficar!

Também chamadas de “strings literais formatadas” (formatted string literals), f-strings são strings com a letra f no início e chaves {} para realizar a interpolação de expressões.

As expressões são processadas em tempo de execução e formatadas utilizando o protocolo __format__ (a regra completa está na documentação oficial das f-strings). Vamos de exemplo:

1
2
3
nome = 'Python Academy'

print(f"Qual o melhor Blog sobre Python? {nome}!")

E a saída seria:

1
Qual o melhor Blog sobre Python? Python Academy!

O que significa o f no print do Python?

O f em print(f"...") não pertence ao print(): ele pertence à string. A letra antes das aspas avisa o Python que aquele texto é uma f-string, então cada {...} é avaliado e trocado pelo valor. O print() só recebe o texto já montado e o mostra na tela (se quiser rever os parâmetros do print() e como ler dados do teclado, veja o guia de input e print no Python).

Compare as duas formas de imprimir a mesma coisa:

1
2
3
4
5
nome = "Ana"
nota = 9.5

print("Aluna:", nome, "- Nota:", nota)   # sem f-string: vários argumentos
print(f"Aluna: {nome} - Nota: {nota}")   # com f-string: um texto só
1
2
Aluna: Ana - Nota: 9.5
Aluna: Ana - Nota: 9.5

O resultado é igual, mas a f-string deixa você controlar cada espaço e pontuação do texto e ainda aplicar formatação ({nota:.1f}, {nome:>10}). Como a f-string é uma string comum, ela funciona em qualquer lugar, não só no print():

1
2
3
4
nome = "Ana"
mensagem = f"Aluna: {nome}"

print(type(mensagem), len(mensagem))
1
<class 'str'> 10

Resumindo: print(f"...") é só a função print() recebendo uma f-string. Você pode usar F maiúsculo também (F"Olá, {nome}"), e o efeito é o mesmo.

Como usar funções dentro de uma f-string?

Como f-strings são processadas em tempo de execução, podemos colocar quase todo tipo de código dentro das expressões.

Aqui um outro exemplo, utilizando chamada de função e mais:

1
2
3
nome = 'python academy'

print(f"Qual o melhor Blog sobre Python? {nome.upper() + '!' * 3}")

Sua saída seria:

1
Qual o melhor Blog sobre Python? PYTHON ACADEMY!!!

Ou ainda:

1
2
3
4
5
import math

x = 0.5

print(f'cos({x}) = {math.cos(x)}')

O output seria:

1
cos(0.5) = 0.8775825618903728

Como acessar dicionários dentro de uma f-string?

Também é possível acessar dicionários dentro de f-strings:

1
2
3
dicionario = dict({'nome': 'Vinícius', 'ocupacao': 'Software Engineer'})

print(f"{dicionario['nome']} é um {dicionario['ocupacao']}")

Seu output seria:

1
Vinícius é um Software Engineer

Strings multi-linha

Também podemos criar f-strings multilinha:

1
2
3
4
5
6
7
8
9
site = 'Python Academy'
titulo = 'f-string no Python'
dificuldade = 'Básico'

print(
  f"Site: {site}\n"
  f"Título: {titulo}\n"
  f"Dificuldade: {dificuldade}"
)

A saída seria a seguinte:

1
2
3
Site: Python Academy
Título: f-string no Python
Dificuldade: Básico

f-string multilinha e com aspas

A técnica acima junta várias f-strings de uma linha só (o Python concatena strings vizinhas automaticamente). Para um bloco de texto maior, use aspas triplas com o f na frente: as quebras de linha digitadas viram quebras de linha no resultado.

1
2
3
4
5
6
7
8
9
10
11
nome = "Ana"
curso = "Python"
horas = 40
nota = 9.5

certificado = f"""Certificado de conclusão
Aluna: {nome}
Curso: {curso} ({horas}h)
Nota final: {nota:.1f}"""

print(certificado)
1
2
3
4
Certificado de conclusão
Aluna: Ana
Curso: Python (40h)
Nota final: 9.5

E as aspas? A regra que funciona em todas as versões do Python 3.6+ é: dentro das chaves, use um tipo de aspa diferente do que abre a f-string. No texto fora das chaves, você pode escapar aspas com \" normalmente.

1
2
3
4
5
6
aluno = {"nome": "Ana", "aprovado": True}

print(f"Aluna: {aluno['nome']}")                                   # " fora, ' dentro
print(f'Situação: {"aprovada" if aluno["aprovado"] else "reprovada"}')  # ' fora, " dentro
print(f"Ela disse: \"{aluno['nome']} passou!\"")                   # \" no texto
print(f"""Ela disse: "{aluno['nome']} passou!" e comemorou.""")    # aspas triplas
1
2
3
4
Aluna: Ana
Situação: aprovada
Ela disse: "Ana passou!"
Ela disse: "Ana passou!" e comemorou.

O que mudou no Python 3.12: a PEP 701 passou a tratar a f-string como parte da gramática do Python. Na prática, a partir do 3.12:

  • dá para repetir as mesmas aspas dentro das chaves: f"{aluno["nome"]}";
  • dá para usar barra invertida dentro da expressão, como em f"{'\n'.join(nomes)}";
  • dá para aninhar f-strings com o mesmo tipo de aspa.

No Python 3.11 ou anterior, esses três casos são SyntaxError. Se o seu código pode rodar em versões diferentes (servidor antigo, Google Colab, máquina da faculdade), prefira a forma compatível: alterne as aspas e tire a barra invertida da expressão guardando o texto numa variável antes.

1
2
3
4
nomes = ["Ana", "Bia"]
quebra = "\n"

print(f"Alunas:\n{quebra.join(nomes)}")  # funciona em qualquer versão
1
2
3
Alunas:
Ana
Bia

Repare que o \n fora das chaves (logo depois de Alunas:) sempre foi permitido. A restrição antiga valia só para a parte da expressão, entre { e }.

Está curtindo esse conteúdo? :thumbsup:

Que tal receber 30 dias de conteúdo direto na sua Caixa de Entrada?

Sua assinatura não pôde ser validada.
Você fez sua assinatura com sucesso.

Assine as PyDicas e receba 30 dias do melhor conteúdo Python na sua Caixa de Entrada: direto e sem enrolação!

Vamos nessa! :wink:

Método de classe __str__ vs __repr__

Você pode até mesmo utilizar objetos instanciados dentro de f-strings. Por exemplo, caso você tenha a seguinte classe:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Carro:
  def __init__(self, marca, modelo, ano):
    self.marca = marca
    self.modelo = modelo
    self.ano = ano

  def __str__(self):
    return f"{self.marca}/{self.modelo} - Ano {self.ano}"

  def __repr__(self):
    return (
      f"Marca: {self.marca}\n"
      f"Modelo: {self.modelo}\n"
      f"Ano: {self.ano}"
    )

Seria possível fazer:

1
2
3
possante = Carro('Ferrari', 'F8 Tributo', '21')

print(f'{possante}')

A saída de código seria:

1
Ferrari/F8 Tributo - Ano 21

A saída padrão é a do método __str__.

Contudo, se quisermos apresentar a representação presente no método __repr__, podemos utilizar flag especial !r.

Veja como:

1
print(f'{possante!r}')

Dessa forma, a saída seria a seguinte:

1
2
3
Marca: Ferrari
Modelo: F8 Tributo
Ano: 21

:bulb: Criei o Ebookr.ai, uma plataforma que usa IA para gerar ebooks profissionais sobre qualquer tema - com capa gerada por IA, infográficos automáticos e exportação em PDF. Confere!

Utilizando formatadores especiais

A Especificação de Formatação (do inglês “Format Specification” - acesse a documentação aqui) oferece modificadores que podem ser utilizados em conjunto com f-strings.

A especificação é bem extensa e contém diversos componentes, portanto sugiro dar uma olhadinha lá.

Sua forma é a seguinte:

1
{[<nome>][!<conversão>][:<modificador>]}

A parte [:<modificador>] é bem complexa e possui os seguintes campos:

1
:[[<preenchimento>]<alinhamento>][<sinal>][#][0][<comprimento>][<grupo>][.<precisão>][<tipo>]

Cada campo desse possibilita um tipo de modificação na string resultante.

Vamos de exemplo!

Um modificador disponível é o símbolo de porcentagem %. Ele serve para formatar saídas numéricas. Veja a mágica:

1
2
3
4
5
6
valor = 5.5 / 40.0

print(
  f'Resultado original: {valor}\n'
  f'Resultado formatado: {valor:.1%}'
)

Olha a saída:

1
2
Resultado original: 0.1375
Resultado formatado: 13.8%

Explicando:

  • O .1 diz que a string resultante deve ter apenas uma casa decimal;
  • O % multiplica o valor por 100 e inclui o % ao final.

Agora um exemplo maluco:

1
2
3
valor = 255

print(f"'{valor:-^10x}'")

E a saída:

1
'----ff----'

Agora vamos com calma:

  • - é o [<preenchimento>]: é esse caracter que vai preencher os espaços vazios;
  • ^ é o [<alinhamento>]: diz como a string deve ser alinhada. No caso, ^ diz que a string deve ser centralizada.
  • 10 é o [<comprimento>]: diz que a string resultante deve ter 10 caracteres.
  • x é o [<tipo>]: diz que a string deve ser convertida em hexadecimal (portanto ff no resultado).

Um tanto complexo, mas conciso!

Tabela de modificadores mais usados

Para não decorar a especificação inteira, segue uma colinha com os modificadores mais comuns (e o resultado real de cada um):

Modificador O que faz Exemplo Resultado
:.2f Arredonda para 2 casas decimais f"{1234.5678:.2f}" 1234.57
:, Separador de milhar f"{1000000:,}" 1,000,000
:,.2f Milhar + 2 casas decimais f"{1234.5678:,.2f}" 1,234.57
:.1% Percentual com 1 casa f"{0.1375:.1%}" 13.8%
:^10 Centraliza em 10 caracteres f"{'Alice':^10}" ' Alice '
:>8 Alinha à direita em 8 caracteres f"{'Alice':>8}" ' Alice'
!r Usa a representação repr() f"{'Alice'!r}" 'Alice'

:bulb: Os modificadores de precisão e alinhamento podem ser combinados e até receber valores dinâmicos: f"{valor:{largura}.2f}" calcula a largura em tempo de execução.

Como arredondar para 2 casas decimais com f-string?

O caso mais comum no dia a dia é formatar valores monetários ou percentuais. Para arredondar para 2 casas decimais, use :.2f:

1
2
3
4
valor = 1234.5678

print(f"{valor:.2f}")
print(f"{valor:,.2f}")

A saída:

1
2
1234.57
1,234.57

O :,.2f ainda inclui o separador de milhar - perfeito para exibir preços.

Como exibir nome e valor para debug? ({var=}, Python 3.8+)

A partir do Python 3.8, as f-strings ganharam a sintaxe self-documenting: basta colocar um = logo após a expressão para imprimir o nome e o valor de uma só vez. É um atalho fantástico para depurar:

1
2
3
4
5
6
7
x = 10
y = 20

print(f"{x=}, {y=}")

total = x + y
print(f"{total=}")

A saída:

1
2
x=10, y=20
total=30

Reúso de aspas e aninhamento (Python 3.12+)

Antes do Python 3.12, você não podia reutilizar dentro da expressão o mesmo tipo de aspa que delimitava a f-string - o jeito era alternar aspas simples e duplas. A PEP 701 (Python 3.12) flexibilizou isso: agora dá para reutilizar aspas e aninhar f-strings livremente.

1
2
3
4
config = {"theme": "dark"}

# A partir do Python 3.12 isso é válido:
print(f"Tema: {config["theme"]}")

A saída:

1
Tema: dark

:warning: Em Python 3.11 ou anterior esse código levanta SyntaxError. Para manter compatibilidade, alterne as aspas: f"Tema: {config['theme']}".

Formatar números: casas decimais, milhar e porcentagem

Tudo o que vem depois dos dois-pontos dentro das chaves é o especificador de formato, descrito na mini-linguagem de especificação de formato da documentação oficial. A ordem dos pedaços é sempre a mesma: preenchimento e alinhamento, sinal, zeros, largura, agrupamento de milhar, precisão e, por último, o tipo.

Nos exemplos abaixo, preco = 1234.5678, n = 42 e nome = "Ana" (os resultados entre aspas mostram os espaços):

Especificador Exemplo Resultado O que faz
:.2f f"{preco:.2f}" 1234.57 2 casas decimais (arredonda)
:,.2f f"{preco:,.2f}" 1,234.57 Milhar com vírgula + 2 casas
:_.2f f"{preco:_.2f}" 1_234.57 Milhar com sublinhado
:.1% f"{0.256:.1%}" 25.6% Multiplica por 100 e põe %
:05d f"{n:05d}" 00042 Inteiro com zeros à esquerda (largura 5)
:+d f"{n:+d}" +42 Sempre mostra o sinal
:>10 f"{nome:>10}" ' Ana' Alinha à direita em 10 posições
:<10 f"{nome:<10}" 'Ana ' Alinha à esquerda em 10 posições
:^10 f"{nome:^10}" ' Ana ' Centraliza em 10 posições
:*^10 f"{nome:*^10}" ***Ana**** Centraliza preenchendo com *
:e f"{preco:e}" 1.234568e+03 Notação científica (6 casas por padrão)
:.2e f"{preco:.2e}" 1.23e+03 Notação científica com 2 casas
:b / :x f"{n:b}" / f"{n:x}" 101010 / 2a Binário / hexadecimal
:08.2f f"{3.14159:08.2f}" 00003.14 Largura 8 com zeros e 2 casas

Três detalhes que confundem muita gente:

  • O tipo tem que combinar com o valor. d, b e x são só para inteiros; f, e e % aceitam int e float. Usar :d num float gera ValueError (veja em Erros comuns). Se estiver em dúvida sobre o tipo da variável, o post sobre tipos de variáveis no Python explica a diferença entre int, float e str.
  • O % do especificador não é o operador de resto. Em {x:.1%} ele só formata a saída; já x % 2 fora das chaves é o operador de módulo que você vê em operadores aritméticos e lógicos.
  • Largura e precisão podem vir de variáveis. Coloque chaves dentro do especificador:
1
2
3
4
5
6
7
nome = "Ana"
largura = 12
print(f"[{nome:^{largura}}]")

valor = 3.14159
for casas in range(1, 4):
    print(f"{valor:.{casas}f}")
1
2
3
4
[    Ana     ]
3.1
3.14
3.142

O mesmo : também formata datas: com um objeto date ou datetime, o especificador aceita os códigos do strftime.

1
2
3
4
from datetime import datetime

agora = datetime(2026, 9, 26, 14, 5)
print(f"{agora:%d/%m/%Y %H:%M}")
1
26/09/2026 14:05

:bulb: Um cuidado com arredondamento: f"{2.675:.2f}" mostra 2.67, e não 2.68. O float guarda 2.675 como um número binário um pouquinho menor que isso. Para dinheiro, onde cada centavo importa, use Decimal("2.675"), que formata como 2.68.

Formatar moeda em reais (R$ 1.234,56)

O especificador :,.2f segue o padrão americano: vírgula no milhar e ponto nos centavos (1,234.56). Não existe um especificador que troque isso sozinho, mas dá para resolver em uma linha com str.translate, que troca vírgula por ponto e ponto por vírgula ao mesmo tempo:

1
2
3
4
5
6
7
8
9
def formatar_reais(valor):
    texto = f"{abs(valor):,.2f}".translate(str.maketrans(",.", ".,"))
    sinal = "-" if valor < 0 else ""
    return f"{sinal}R$ {texto}"

print(formatar_reais(1234.56))
print(formatar_reais(1234567.891))
print(formatar_reais(0.5))
print(formatar_reais(-89.9))
1
2
3
4
R$ 1.234,56
R$ 1.234.567,89
R$ 0,50
-R$ 89,90

Por que uma função? Porque ela resolve de uma vez o sinal de negativo (que ficaria como R$ -89,90), os zeros dos centavos e o milhar, e você reaproveita em todo o programa. A mesma função aceita Decimal: formatar_reais(Decimal("2.675")) devolve R$ 2,68.

Alternativa com locale: o módulo locale formata no padrão do país configurado no sistema.

1
2
3
4
5
6
import locale

locale.setlocale(locale.LC_ALL, "pt_BR.UTF-8")

print(locale.currency(1234.56, grouping=True))
print(f"{1234.56:n}")
1
2
R$ 1.234,56
1.234,56

O problema é que isso depende de o locale pt_BR.UTF-8 estar instalado na máquina. Em muitos servidores e contêineres ele não vem instalado (e no Windows o nome do locale pode ser outro), e aí o setlocale falha com locale.Error: unsupported locale setting. Além disso, o setlocale muda a configuração do programa inteiro. Por isso a função com translate costuma ser a escolha mais segura para exercícios e scripts simples.

Casos Práticos

1. Logs Formatados

1
2
3
4
5
6
7
8
9
import datetime

user_id = 123
action = "login"
timestamp = datetime.datetime.now()

log = f"[{timestamp:%Y-%m-%d %H:%M:%S}] User {user_id} performed {action.upper()}"
print(log)
# [2025-12-10 10:30:45] User 123 performed LOGIN (a data e a hora variam)

2. Queries SQL Dinâmicas

1
2
3
4
5
6
7
8
9
table = "users"
field = "email"
value = "[email protected]"

query = f"SELECT * FROM {table} WHERE {field} = '{value}'"
print(query)
# SELECT * FROM users WHERE email = '[email protected]'

# ⚠️ ATENÇÃO: Use prepared statements em produção!

3. Templates HTML

1
2
3
4
5
6
7
8
9
10
11
username = "Alice"
points = 1250

html = f"""
<div class="user-card">
    <h2>{username}</h2>
    <p>Pontos: {points:,}</p>
    <span class="badge">{"VIP" if points > 1000 else "Regular"}</span>
</div>
"""
print(html)

4. Debug Rápido (Python 3.8+)

1
2
3
4
5
6
7
8
9
10
11
12
13
x = 10
y = 20

# Modo antigo
print(f"x: {x}, y: {y}")

# Modo novo (debug)
print(f"{x=}, {y=}")
# x=10, y=20

total = x + y
print(f"{total=}")
# total=30

Saber quando usar cada ferramenta de formatação é o tipo de detalhe que separa quem só copia código de quem entende Python de verdade. Essa profundidade é o que a gente trabalha, aula a aula, na Jornada Python:

f-strings vs .format() vs %

1
2
3
4
5
6
7
8
9
10
11
12
13
nome = "Alice"
idade = 25

# % (estilo legado; ainda funciona no Python 3)
result1 = "Nome: %s, Idade: %d" % (nome, idade)

# .format() (Python 2.6+)
result2 = "Nome: {}, Idade: {}".format(nome, idade)

# f-string (Python 3.6+) - RECOMENDADO!
result3 = f"Nome: {nome}, Idade: {idade}"

# Todos produzem: "Nome: Alice, Idade: 25"

E como usar o .format()? Ele usa as mesmas chaves e o mesmo especificador de formato depois dos dois-pontos, mas os valores entram como argumentos do método. A grande vantagem é poder escrever o modelo antes e preencher depois, várias vezes:

1
2
3
4
5
modelo = "Olá, {nome}! Seu saldo é R$ {saldo:.2f}."

print(modelo.format(nome="Ana", saldo=150))
print(modelo.format(nome="Bia", saldo=87.5))
print("{0} e {1}, {1} e {0}".format("A", "B"))  # índices reaproveitam valores
1
2
3
Olá, Ana! Seu saldo é R$ 150.00.
Olá, Bia! Seu saldo é R$ 87.50.
A e B, B e A

Com f-string isso não é possível do mesmo jeito, porque ela é avaliada no momento em que a linha roda: as variáveis precisam existir ali.

Performance

1
2
3
4
5
6
7
8
9
10
11
12
13
import timeit

nome = "Alice"
idade = 25

# Benchmark
format_percent = timeit.timeit(lambda: "Nome: %s, Idade: %d" % (nome, idade), number=1000000)
format_dot = timeit.timeit(lambda: "Nome: {}, Idade: {}".format(nome, idade), number=1000000)
format_f = timeit.timeit(lambda: f"Nome: {nome}, Idade: {idade}", number=1000000)

print(f"% : {format_percent:.4f}s")
print(f".format(): {format_dot:.4f}s")
print(f"f-string : {format_f:.4f}s")

Resultado: na prática, as f-strings costumam ser as mais rápidas das três - o Python transforma a f-string em instruções próprias de montagem de texto já na compilação, sem chamar um método como .format(). Rodando o benchmark acima no Python 3.10, a ordem foi f-string, depois % e por último .format(). A margem exata varia conforme a versão do Python e o hardware, então rode o benchmark acima na sua máquina para conferir.

Quando Usar Cada Um?

✅ Use f-string (recomendado!):

  • Python 3.6+ disponível
  • Performance importante
  • Código legível
  • Debug rápido ({var=})

✅ Use .format():

  • Compatibilidade Python 2.6-3.5
  • Templates reutilizáveis
  • Formatação complexa

❌ Evite %:

  • Sintaxe antiga
  • Menos legível
  • Mais lento

A mesma decisão, em formato de tabela:

Situação Use Exemplo
Mostrar variáveis no print() ou montar texto no código f-string f"Olá, {nome}"
Modelo de texto definido antes dos valores (arquivo, configuração, tradução) .format() modelo.format(nome=nome)
Mensagens do módulo logging % com argumentos do logger logging.info("Usuário %s entrou", nome)
Manter código antigo que já usa % % "%.2f" % valor
Montar consultas SQL com dados do usuário Nenhum dos três: placeholders do driver cursor.execute("... WHERE email = ?", (email,))

Erros comuns

Estes são os erros que mais aparecem com f-strings. As mensagens abaixo são reais, geradas rodando cada script com python3 main.py no Python 3.10.

1. Esquecer o f (o Python imprime as chaves)

1
2
nome = "Ana"
print("Olá, {nome}!")
1
Olá, {nome}!

Não dá erro nenhum, e por isso passa despercebido. Correção: coloque o f antes das aspas: print(f"Olá, {nome}!").

2. SyntaxError ao escrever uma chave sozinha no texto

1
2
nome = "Ana"
print(f"Use {nome} entre chaves: }")
1
2
3
  File "main.py", line 2
    print(f"Use {nome} entre chaves: }")
SyntaxError: f-string: single '}' is not allowed

Correção: numa f-string, chave literal se escreve dobrada: {{ vira { e }} vira }. Para mostrar o valor entre chaves, use três de cada lado:

1
2
3
nome = "Ana"
print(f"{{nome}} vira {nome}")
print(f"{{{nome}}}")
1
2
{nome} vira Ana
{Ana}

3. ValueError ao usar um especificador que não combina com o tipo

1
2
media = 7.5
print(f"Média: {media:d}")
1
2
3
4
Traceback (most recent call last):
  File "main.py", line 2, in <module>
    print(f"Média: {media:d}")
ValueError: Unknown format code 'd' for object of type 'float'

Correção: d é só para inteiros. Para um float, use f"{media:.0f}" (arredonda para 8, sem casas) ou f"{media:.1f}" (7.5). Se você quer mesmo a parte inteira, converta antes: f"{int(media):d}" (7).

4. ValueError ao formatar um número que ainda é texto

1
2
preco = "19.9"  # veio do input()
print(f"R$ {preco:.2f}")
1
2
3
4
Traceback (most recent call last):
  File "main.py", line 2, in <module>
    print(f"R$ {preco:.2f}")
ValueError: Unknown format code 'f' for object of type 'str'

Correção: o input() sempre devolve str, e o especificador :.2f só funciona com número. Converta na leitura: preco = float(input("Preço: ")).

5. SyntaxError ao repetir as aspas dentro das chaves (Python 3.11 ou anterior)

1
2
aluno = {"nome": "Ana"}
print(f"Aluno: {aluno["nome"]}")
1
2
3
  File "main.py", line 2
    print(f"Aluno: {aluno["nome"]}")
SyntaxError: f-string: unmatched '['

No Python 3.12 ou mais novo, esse mesmo código roda e imprime Aluno: Ana (PEP 701). Correção compatível com todas as versões: alterne as aspas, f"Aluno: {aluno['nome']}". O mesmo vale para barra invertida dentro das chaves: no 3.10, f"{'\n'.join(nomes)}" falha com SyntaxError: f-string expression part cannot include a backslash; guarde o "\n" numa variável antes.

Exercícios resolvidos

Tente resolver cada um antes de abrir a solução. Todas as saídas foram conferidas rodando o código.

Exercício 1. Com nome = "Ana" e idade = 20, imprima a frase Ana tem 20 anos. usando uma f-string.

Ver solução
1
2
3
nome = "Ana"
idade = 20
print(f"{nome} tem {idade} anos.")

Saída: Ana tem 20 anos.

Cada {...} é trocado pelo valor da variável, e o texto em volta (espaços e ponto final) fica exatamente como você escreveu.

Exercício 2. Calcule a média das notas 7, 8.5 e 9 e mostre Média: seguido do valor com duas casas decimais.

Ver solução
1
2
3
n1, n2, n3 = 7, 8.5, 9
media = (n1 + n2 + n3) / 3
print(f"Média: {media:.2f}")

Saída: Média: 8.17

A média real é 8.1666.... O :.2f arredonda para duas casas; sem ele, o print mostraria todas as casas do float.

Exercício 3. Faça um programa que leia o dia, o mês e o ano digitados pelo usuário e imprima a data no formato dd/mm/aaaa, com zero à esquerda (dia 5, mês 3 e ano 2026 devem aparecer como 05/03/2026).

Ver solução
1
2
3
4
dia = int(input("Dia: "))   # Dia: 5
mes = int(input("Mês: "))   # Mês: 3
ano = int(input("Ano: "))   # Ano: 2026
print(f"{dia:02d}/{mes:02d}/{ano}")

Saída: 05/03/2026

O :02d exige largura 2 e completa com zero à esquerda. Por isso o int() na leitura é obrigatório: com o texto "5", o :02d daria ValueError.

Exercício 4. (Questão de prova) Qual é a saída de print(f"{2/3:.2f}")?

a) 0.66
b) 0.67
c) 0.6666666666666666
d) 2/3

Ver solução
1
print(f"{2/3:.2f}")

Saída: 0.67

Alternativa b. A expressão 2/3 é calculada (0.666...) e o :.2f arredonda para duas casas, não trunca. A alternativa d seria a saída só se o 2/3 estivesse fora das chaves.

Exercício 5. (Questão de prova) Com nome = "Ana", qual linha imprime exatamente {Ana}?

a) print(f"{nome}")
b) print(f"{{nome}}")
c) print(f"{{{nome}}}")
d) print("{nome}")

Ver solução
1
2
3
4
5
nome = "Ana"
print(f"{nome}")
print(f"{{nome}}")
print(f"{{{nome}}}")
print("{nome}")

Saída:

1
2
3
4
Ana
{nome}
{Ana}
{nome}

Alternativa c. Cada {{ e }} vira uma chave literal, e o par de chaves do meio interpola a variável. A b mostra a palavra nome entre chaves, e a d nem é f-string.

Exercício 6. Imprima a lista de produtos abaixo como uma tabela alinhada: nome à esquerda em 15 posições e preço à direita com duas casas decimais.

produtos = [("Café", 18.9), ("Pão de queijo", 4.5), ("Suco", 9.75)]

Ver solução
1
2
3
4
produtos = [("Café", 18.9), ("Pão de queijo", 4.5), ("Suco", 9.75)]

for nome, preco in produtos:
    print(f"{nome:<15}R$ {preco:>6.2f}")

Saída:

1
2
3
Café           R$  18.90
Pão de queijo  R$   4.50
Suco           R$   9.75

O :<15 reserva 15 posições para o nome e o :>6.2f alinha os preços pela direita, então os pontos decimais ficam um embaixo do outro. O for com desempacotamento de tuplas é explicado no post de estruturas de repetição no Python.

Exercício 7. Um aluno acertou 17 de 20 questões. Mostre o aproveitamento em porcentagem com uma casa decimal, sem multiplicar por 100 na mão.

Ver solução
1
2
3
acertos = 17
total = 20
print(f"Aproveitamento: {acertos / total:.1%}")

Saída: Aproveitamento: 85.0%

O tipo % multiplica 0.85 por 100 e acrescenta o símbolo. A precisão .1 define uma casa decimal.

Exercício 8. Um salário de R$ 3.500,50 teve aumento de 12,5%. Mostre o novo salário no padrão brasileiro (R$ 3.938,06).

Ver solução
1
2
3
4
5
6
7
8
def formatar_reais(valor):
    texto = f"{abs(valor):,.2f}".translate(str.maketrans(",.", ".,"))
    sinal = "-" if valor < 0 else ""
    return f"{sinal}R$ {texto}"

salario = 3500.50
novo = salario * 1.125
print(f"Novo salário: {formatar_reais(novo)}")

Saída: Novo salário: R$ 3.938,06

O valor calculado é 3938.0625. O :,.2f gera 3,938.06 e o translate troca vírgula e ponto de lugar ao mesmo tempo. Repare que dá para chamar uma função dentro das chaves de outra f-string.

Conclusão

Neste guia de f-strings, você aprendeu:

✅ Sintaxe - f"{variavel}" simples e legível
✅ Formatação - Largura, alinhamento, precisão, data/hora
✅ Debug - f"{var=}" (Python 3.8+)
✅ Casos práticos - Logs, SQL, HTML, debug
✅ Performance - geralmente mais rápida que .format() e %

Principais lições:

  • F-strings são o padrão moderno (Python 3.6+)
  • Sintaxe limpa e legível
  • Performance superior
  • {var=} é ótimo para debug
  • Use :.2f para precisão, :>10 para alinhamento

Próximos passos:

  • Explore Strings em Python
  • Aprenda expressões dentro de f-strings: f"{2 + 2}"
  • Pratique formatação de datas com {dt:%Y-%m-%d}
  • Estude f-strings multi-linha para templates
  • Quer praticar formatação de saída com projetos guiados, do básico ao avançado? Conheça o curso de Python completo da Jornada Python

Uma boa né?! :sweat_smile:

Até a próxima, Pythonista!

Perguntas frequentes

O que é uma f-string no Python?

Uma f-string é uma string literal formatada (PEP 498, Python 3.6+) prefixada com f, que interpola expressões direto nas chaves {}. Ex.: f"Olá {nome}". As expressões são avaliadas em tempo de execução, o que a torna mais legível que .format() e %.

Como arredondar para 2 casas decimais com f-string?

Para arredondar para 2 casas decimais, use o modificador :.2f dentro das chaves: f"{valor:.2f}". Com valor = 1234.5678, o resultado é 1234.57. Combine com , para separador de milhar: f"{valor:,.2f}" gera 1,234.57.

Como alinhar e preencher texto com f-string?

Para alinhar texto, use :< (esquerda), :> (direita) ou :^ (centro) seguido do comprimento. Ex.: f"{nome:^10}" centraliza em 10 caracteres. Coloque um caractere antes do alinhamento para preencher: f"{nome:*^10}" usa * no lugar dos espaços.

Qual a diferença entre f-string e .format()?

A f-string avalia a expressão inline (f"{nome}"), enquanto .format() recebe os valores como argumentos ("{}".format(nome)). A f-string costuma ser mais rápida e legível; já .format() ainda é útil para templates reutilizáveis e compatibilidade com Python anterior ao 3.6.

Como exibir nome e valor de uma variável para debug?

Para debug, use a sintaxe self-documenting f"{var=}" (Python 3.8+), que imprime o nome e o valor da variável. Ex.: com total = 30, f"{total=}" produz total=30. Funciona com expressões também: f"{x + y=}".

O que significa o f no print(f”…”) do Python?

O f antes das aspas transforma o texto em uma f-string (string literal formatada, Python 3.6+). Tudo o que estiver entre chaves é avaliado e trocado pelo valor: com nome = "Ana", print(f"Olá, {nome}") mostra Olá, Ana. O f não é do print(): a f-string é uma str comum e pode ser guardada em variável, como msg = f"Olá, {nome}". Sem o f, o Python imprime as chaves literalmente.

Como formatar um valor em reais (R$ 1.234,56) com f-string?

O especificador :,.2f usa o padrão americano (1,234.56). Para o padrão brasileiro, formate e depois troque vírgula por ponto e vice-versa: f"R$ {valor:,.2f}".translate(str.maketrans(",.", ".,")). Com valor = 1234.56, o resultado é R$ 1.234,56. Outra opção é o módulo locale com locale.setlocale(locale.LC_ALL, "pt_BR.UTF-8") e locale.currency(valor, grouping=True), que depende de o sistema ter o locale pt_BR instalado.

(Questão de prova) Qual é a saída de print(f”{2/3:.2f}”) em Python?

A saída é 0.67. A divisão 2/3 resulta em 0.6666..., e o especificador :.2f exibe o número com exatamente duas casas decimais, arredondando (não truncando) o valor. Por isso a resposta não é 0.66 nem 0.6666.

Começe agora sua Jornada na Programação!

Não deixe para amanhã o sucesso que você pode começar a construir hoje!

#newsletter Olá :wave: Curtiu o artigo? Então faça parte da nossa Newsletter! Privacidade Não se preocupe, respeitamos sua privacidade. Você pode se descadastrar a qualquer momento.