f-strings: interpolação moderna e formatação avançada

1. Introdução às f-strings: o que são e por que usar

As f-strings (ou formatted string literals) foram introduzidas no Python 3.6 e representam a maneira mais moderna, legível e performática de interpolar variáveis em strings. A sintaxe é simples: basta prefixar a string com f ou F e usar chaves {} para inserir expressões.

nome = "Alice"
idade = 30
print(f"Meu nome é {nome} e tenho {idade} anos.")
# Saída: Meu nome é Alice e tenho 30 anos.

Comparado com métodos antigos, as f-strings oferecem vantagens claras:

# Método % (difícil de ler com muitas variáveis)
print("Meu nome é %s e tenho %d anos." % (nome, idade))

# Método .format() (mais verboso)
print("Meu nome é {} e tenho {} anos.".format(nome, idade))

# Concatenação (propensa a erros e pouco elegante)
print("Meu nome é " + nome + " e tenho " + str(idade) + " anos.")

Além da legibilidade superior, f-strings são mais rápidas que as alternativas, pois a interpolação é resolvida em tempo de compilação.

2. Interpolação de variáveis e expressões

Você pode inserir não apenas variáveis, mas qualquer expressão Python válida dentro das chaves:

a, b = 10, 5
print(f"Soma: {a + b}, Produto: {a * b}")
# Saída: Soma: 15, Produto: 50

print(f"Maior valor: {max(a, b)}")
# Saída: Maior valor: 10

Chamadas de função também funcionam diretamente:

def calcular_desconto(preco, percentual):
    return preco * (1 - percentual / 100)

preco_original = 200
print(f"Preço com desconto: R$ {calcular_desconto(preco_original, 15):.2f}")
# Saída: Preço com desconto: R$ 170.00

3. Formatação de números com f-strings

A formatação numérica é um dos pontos fortes das f-strings. Você pode controlar largura, alinhamento, precisão decimal e muito mais:

pi = 3.1415926535
print(f"Pi com 2 casas: {pi:.2f}")       # 3.14
print(f"Pi com 4 casas: {pi:.4f}")       # 3.1416

# Notação científica
numero_grande = 123456789
print(f"Notação científica: {numero_grande:.2e}")  # 1.23e+08

# Porcentagens
taxa = 0.1875
print(f"Taxa: {taxa:.1%}")  # 18.8%

# Moeda com separadores de milhar
preco = 1234567.89
print(f"Preço: R$ {preco:,.2f}")  # R$ 1,234,567.89

4. Formatação de strings e caracteres especiais

Strings também podem ser formatadas com precisão e alinhamento:

texto = "Python é incrível"
print(f"Truncado: {texto:.10}")  # Python é i
print(f"Completo: {texto}")      # Python é incrível

# Preenchimento com caracteres personalizados
nome = "João"
print(f"{nome:_>20}")  # ________________João
print(f"{nome:_<20}")  # João________________
print(f"{nome:_^20}")  # _______João________

Para incluir chaves literais, use {{ e }}:

valor = 42
print(f"{{Chave literal}} e valor: {valor}")
# Saída: {Chave literal} e valor: 42

5. Alinhamento e espaçamento avançados

O alinhamento pode ser dinâmico, usando variáveis para definir largura:

largura = 30
print(f"{'Esquerda':<{largura}} Fim")
print(f"{'Direita':>{largura}} Fim")
print(f"{'Centro':^{largura}} Fim")

Isso é especialmente útil para criar tabelas alinhadas:

dados = [("Alice", 25, 4500.50), ("Bob", 32, 3200.00), ("Charlie", 28, 5100.75)]

print(f"{'Nome':<10} {'Idade':>6} {'Salário':>10}")
print("-" * 28)
for nome, idade, salario in dados:
    print(f"{nome:<10} {idade:>6} R$ {salario:>8.2f}")

# Saída:
# Nome       Idade   Salário
# ----------------------------
# Alice        25 R$  4500.50
# Bob          32 R$  3200.00
# Charlie      28 R$  5100.75

6. f-strings com datas, booleanos e objetos complexos

Objetos datetime podem ser formatados com os códigos do strftime:

from datetime import datetime

agora = datetime.now()
print(f"Data: {agora:%d/%m/%Y}")
print(f"Hora: {agora:%H:%M:%S}")
print(f"Completo: {agora:%d de %B de %Y às %H:%M}")
# Saída: Data: 15/03/2025, Hora: 14:30:45, Completo: 15 de março de 2025 às 14:30

Booleanos e None também podem ser tratados:

ativo = True
print(f"Status: {ativo}")  # Status: True

# Formatação condicional inline (próximo tópico)

Para objetos personalizados, implemente o método __format__:

class Produto:
    def __init__(self, nome, preco):
        self.nome = nome
        self.preco = preco

    def __format__(self, format_spec):
        if format_spec == 'resumo':
            return f"{self.nome}: R$ {self.preco:.2f}"
        return str(self)

produto = Produto("Notebook", 3500.00)
print(f"{produto:resumo}")  # Notebook: R$ 3500.00

7. Expressões condicionais e operador ternário dentro de f-strings

O operador ternário permite lógica condicional inline:

idade = 17
print(f"Status: {'Maior de idade' if idade >= 18 else 'Menor de idade'}")
# Saída: Status: Menor de idade

nota = 7.5
print(f"Conceito: {'Aprovado' if nota >= 6 else 'Reprovado'} (Nota: {nota:.1f})")
# Saída: Conceito: Aprovado (Nota: 7.5)

Combine com formatação para resultados mais ricos:

saldo = -150.75
print(f"Saldo: {'R$ ' + f'{abs(saldo):,.2f}' if saldo < 0 else f'R$ {saldo:,.2f}'} (negativo)")
# Saída: Saldo: R$ 150,75 (negativo)

Cuidado com expressões muito complexas — se a lógica ficar difícil de ler, extraia para uma variável antes.

8. Boas práticas, erros comuns e dicas finais

Evite expressões com efeitos colaterais dentro das f-strings:

# Ruim: modifica estado dentro da f-string
lista = [1, 2, 3]
print(f"Removido: {lista.pop()}")  # Funciona, mas confuso

# Bom: faça a operação antes
ultimo = lista.pop()
print(f"Removido: {ultimo}")

Cuidado com f-strings em logging — o módulo logging faz lazy evaluation, então use % para evitar processamento desnecessário:

import logging
logging.basicConfig(level=logging.DEBUG)

# Ruim: sempre avalia a expressão, mesmo se o log não for emitido
logging.debug(f"Valor calculado: {funcao_custosa()}")

# Bom: só avalia se o nível de logging permitir
logging.debug("Valor calculado: %s", funcao_custosa())

f-strings aninhadas são possíveis, mas use com moderação:

valor = 123.456
print(f"Formatado: {f'{valor:.2f}'}")  # Formatado: 123.46

Debugging rápido com f"{var=}" (Python 3.8+):

x = 42
y = 3.14
print(f"{x=}, {y=}")  # x=42, y=3.14
print(f"{x + y=}")     # x + y=45.14

f-strings multi-linha podem ser criadas com parênteses:

nome = "Maria"
profissao = "Engenheira"
mensagem = (
    f"Olá, meu nome é {nome}.\n"
    f"Trabalho como {profissao} há 5 anos.\n"
    f"Prazer em conhecê-lo!"
)
print(mensagem)

As f-strings revolucionaram a forma como trabalhamos com strings em Python. Elas combinam performance, legibilidade e poder de formatação em uma sintaxe elegante. Domine esse recurso e seus projetos ficarão mais limpos e eficientes.

Referências