Usuários de países diferentes esperam separadores decimais, símbolos de moeda, nomes de meses e regras de ordenação compatíveis com sua cultura. O módulo locale no Python oferece acesso ao mecanismo de locale do sistema operacional para formatar e interpretar esses valores.
O recurso exige cuidado porque o locale é uma propriedade global do processo, herdada da biblioteca C. Alterar a configuração afeta outras partes da aplicação e normalmente não é seguro em múltiplas threads. Neste guia você aprenderá a inicializar o locale, trabalhar com categorias, números, moedas, datas, ordenação e encodings, além de escolher alternativas para servidores concorrentes.
O conteúdo complementa nossos artigos sobre Decimal, zoneinfo, statistics, platform e sysconfig.
O que é locale
Locale é um conjunto de convenções culturais mantidas pelo sistema. Ele pode definir separador decimal, agrupamento de milhares, símbolo de moeda, posição do sinal, nomes de meses, formato de data e ordem de collation.
Os nomes disponíveis dependem da plataforma e da configuração instalada. Um locale presente em um servidor pode não existir em outro.
O locale inicial do processo
Programas C começam normalmente no locale portátil C. O Python configura aspectos de LC_CTYPE durante a inicialização para lidar com o encoding, mas outras categorias permanecem no comportamento padrão até a aplicação pedir as preferências do usuário.
import locale
locale.setlocale(locale.LC_ALL, "")Uma string vazia solicita o locale padrão do usuário, normalmente definido por variáveis de ambiente ou configuração do sistema.
Consultar sem alterar
atual = locale.setlocale(locale.LC_ALL)
print(atual)Quando o segundo argumento é omitido, setlocale() devolve a configuração atual. A string retornada pode ser usada para restaurar o estado, mas salvar e restaurar em código concorrente continua perigoso.
setlocale não é thread-safe
A alteração é global ao processo na maioria dos sistemas. Uma thread pode mudar o separador decimal enquanto outra está formatando um relatório.
Defina o locale uma vez no início de um programa de desktop ou linha de comando e não o altere depois. Em servidores que atendem usuários com culturas diferentes, use uma biblioteca que aceite o locale como argumento por operação.
Categorias de locale
LC_NUMERIC: números.LC_MONETARY: moedas.LC_TIME: datas e horários.LC_COLLATE: ordenação de strings.LC_CTYPE: classificação e encoding do ambiente.LC_MESSAGES: mensagens do sistema em plataformas POSIX.LC_ALL: combinação de todas.
Alterar somente a categoria necessária reduz efeitos colaterais, mas o estado continua global.
Tratar locale indisponível
try:
locale.setlocale(locale.LC_ALL, "pt_BR.UTF-8")
except locale.Error:
locale.setlocale(locale.LC_ALL, "")Não presuma que o nome pt_BR.UTF-8 funciona em Windows ou em uma imagem de container mínima. Faça a disponibilidade do locale parte do deploy ou forneça fallback explícito.
Normalizar nomes
nome = locale.normalize("pt_BR.UTF-8")A função tenta adaptar aliases ao formato aceito pelo sistema, mas não instala locales ausentes e pode devolver o texto original quando não consegue normalizar.
Convenções numéricas e monetárias
convencoes = locale.localeconv()
print(convencoes["decimal_point"])
print(convencoes["thousands_sep"])
print(convencoes["currency_symbol"])O dicionário também informa agrupamento, casas decimais monetárias, posição do símbolo e sinais. Alguns campos podem usar CHAR_MAX para indicar ausência de especificação.
Formatar números
texto = locale.format_string(
"%.2f",
1234567.89,
grouping=True,
)A função usa convenções de LC_NUMERIC. Ela segue a sintaxe do operador %, não a mini-linguagem completa de f-strings.
Localizar uma string numérica
normalizada = "1234567.89"
localizada = locale.localize(normalizada, grouping=True)localize(), disponível desde Python 3.10, converte uma representação normalizada para o formato cultural atual.
Interpretar números localizados
valor = locale.atof("1.234,56")O exemplo depende de um locale que use ponto para milhares e vírgula decimal. atof() chama delocalize() e depois converte com float por padrão.
Para dinheiro, evite float e passe Decimal como função.
from decimal import Decimal
valor = locale.atof("1.234,56", func=Decimal)Interpretar inteiros
quantidade = locale.atoi("1.234")Valide limites e rejeite formatos ambíguos. Um texto produzido por uma cultura diferente pode ser interpretado incorretamente em vez de gerar erro.
delocalize
normalizado = locale.delocalize("1.234,56")
print(normalizado) # 1234.56 no locale correspondenteA função remove agrupamento e substitui o separador decimal. Ela não valida regras de negócio, quantidade de casas ou sinal permitido.
Formatar moeda
texto = locale.currency(
1234.50,
symbol=True,
grouping=True,
)currency() não funciona no locale C. Configure um locale monetário válido antes de usá-la.
O símbolo local pode ser ambíguo, como $. Para documentos internacionais, considere international=True ou armazene o código ISO da moeda separadamente.
Locale não define a moeda do valor
O locale escolhe como exibir, não qual moeda um número representa. Um usuário brasileiro pode visualizar uma conta em dólares. Mantenha valor e código monetário como dados explícitos.
Datas e horários
time.strftime() usa LC_TIME para nomes de meses, dias e formatos culturais.
from datetime import datetime
texto = datetime.now().strftime("%A, %d de %B de %Y")Locale não substitui timezone. Converta o instante com zoneinfo antes de formatar.
Consultar formatos do sistema
Em plataformas compatíveis, nl_langinfo() pode devolver formatos de data, nomes de meses, encoding, separador decimal e outros dados.
if hasattr(locale, "nl_langinfo"):
formato = locale.nl_langinfo(locale.D_FMT)As constantes disponíveis variam. Proteja chamadas específicas e teste o sistema real.
Ordenação cultural
A ordem Unicode ou ASCII nem sempre coincide com a ordem esperada por usuários.
palavras = ["ação", "ábaco", "zebra"]
ordenadas = sorted(palavras, key=locale.strxfrm)strxfrm() transforma a string em uma chave adequada ao locale atual. É mais eficiente que chamar strcoll() repetidamente durante uma ordenação.
strcoll
comparacao = locale.strcoll("fã", "foo")O retorno negativo, zero ou positivo indica ordem. O resultado depende de LC_COLLATE.
Ordenação não é identidade
Duas strings consideradas próximas na collation não são necessariamente iguais para login, chave ou deduplicação. Para identidade, use regras Unicode e de domínio separadas.
Encoding preferido
encoding = locale.getpreferredencoding(False)A função fornece uma estimativa do encoding preferido para texto. Em modo UTF-8 do Python e Android, retorna UTF-8.
Para novos arquivos e protocolos, declare UTF-8 explicitamente. Não dependa do locale para formatos persistentes.
getencoding
Desde Python 3.11, getencoding() consulta o encoding do locale atual e ignora o modo UTF-8 do Python.
encoding_atual = locale.getencoding()Escolha a função conforme a pergunta: preferência do usuário ou encoding efetivo de LC_CTYPE.
getlocale
lingua, encoding = locale.getlocale(locale.LC_NUMERIC)O locale C é representado como (None, None). LC_ALL não é aceito por getlocale().
Variáveis de ambiente
Em POSIX, LC_ALL, categorias específicas e LANG influenciam a configuração. Containers frequentemente falham por declarar um locale que não foi instalado.
Prefira imagens com UTF-8 configurado e teste o processo com o mesmo ambiente do deploy.
Locale C e C.UTF-8
O locale C é portátil e usa convenções simples. C.UTF-8 é comum em Linux, mas não é garantido em todas as plataformas.
Python possui mecanismos de coerção e modo UTF-8 para reduzir problemas de encodings inválidos em containers e SSH.
Bibliotecas não devem mudar o locale
Uma biblioteca reutilizável não sabe quais outras threads e componentes estão ativos. Chamar setlocale() dentro de uma função pública cria um efeito global surpreendente.
Receba dados já normalizados ou aceite um formatter externo.
Servidores web
Não altere o locale para cada requisição. Duas requisições simultâneas podem misturar vírgulas, pontos, moedas e nomes de meses.
Use bibliotecas de internacionalização com objetos de locale independentes, como Babel, ou implemente formatação determinística baseada em configuração explícita.
gettext para traduções
Locale cuida de convenções culturais, não da tradução completa de textos da aplicação. Para catálogos de mensagens, use o módulo gettext.
As funções gettext expostas por locale atendem integrações com bibliotecas C, mas aplicações Python normalmente devem usar o módulo dedicado.
Testes
Testes devem verificar locales realmente instalados e pular de maneira explícita quando não estiverem disponíveis. Não altere o locale global em paralelo.
def tentar_locale(nome):
try:
locale.setlocale(locale.LC_ALL, nome)
except locale.Error:
return False
return TrueExecute testes em processos separados quando precisar validar várias culturas.
Segurança
Strings localizadas ainda são entrada externa. Limite tamanho, valide o conjunto de caracteres e não use o resultado como SQL, comando ou caminho.
Formato cultural não substitui validação de domínio. Uma quantia negativa, infinita ou com casas excessivas pode ser sintaticamente válida e ainda proibida.
Erros frequentes
- Alterar o locale em cada requisição.
- Presumir que um nome existe em todos os sistemas.
- Usar float para dinheiro.
- Confundir locale com timezone.
- Confundir locale com código de moeda.
- Comparar versões ou números localizados como strings.
- Usar collation como igualdade.
- Deixar uma biblioteca mudar o estado global.
Boas práticas
- Configure o locale uma vez no startup de programas simples.
- Use categorias específicas quando possível.
- Trate
locale.Error. - Use Decimal para quantias.
- Mantenha moeda e timezone explícitos.
- Use
strxfrm()para ordenação repetida. - Prefira UTF-8 em dados persistentes.
- Use formatters independentes em servidores concorrentes.
Conclusão
O módulo locale no Python conecta a aplicação às convenções culturais instaladas no sistema para números, moedas, datas, encodings e ordenação.
Seu principal limite é o estado global e não thread-safe. Ele funciona bem em ferramentas locais configuradas uma vez, mas servidores multiusuário devem preferir formatters independentes por requisição. Consulte a documentação oficial de locale e o Unicode CLDR para aplicações internacionais mais amplas.







