Template String
Imagine que você criou uma automação para envio de email aos funcionários da empresa que você trabalha e que no corpo desse email existem dados que precisam ser alterados dinamicamente, exatamente aqui Template String entra em ação.
Veja esse caso de uso:
from string import Template
tmpl_email = """
Caro $employee_name,
Espero que este e-mail o encontre bem. Gostaríamos de informar que realizamos uma revisão salarial anual e,
como resultado, houve um ajuste no seu salário com base no índice de correção pela inflação.
Após análises e cálculos cuidadosos, verificamos que o índice de inflação acumulada nos últimos 12 meses foi de
$idx_inflation_rate. Com base nesse valor, o seu salário será corrigido para refletir a variação do custo de vida e
garantir que você seja devidamente compensado.
A partir do próximo mês, seu salário corrigido será de $salary. Essa correção foi aplicada retroativamente, o que s
ignifica que você também receberá um valor adicional referente ao período desde a última atualização salarial.
Se você tiver alguma dúvida sobre o cálculo ou qualquer outro aspecto relacionado à sua remuneração, fique à vontade
para entrar em contato com o setor de Recursos Humanos. Estamos aqui para ajudar e fornecer qualquer esclarecimento
adicional que você precise.
Agradecemos sua dedicação e contribuição para a empresa. Reconhecemos que seu trabalho é fundamental
para o nosso sucesso contínuo, e a atualização salarial é uma forma de valorizarmos seus esforços.
Parabenizamos pelo seu desempenho e estamos ansiosos para continuar trabalhando juntos.
Atenciosamente,
$sender_name
$sender_role
$sender_company
"""
to_replace = {
'employee_name': 'João da Silva',
'idx_inflation_rate': '5%',
'salary': 'R$ 1.500,00',
'sender_name': 'Maria de Souza',
'sender_role': 'Gerente de RH',
'sender_company': 'Empresa XYZ'
}
to_replace_two = {
'employee_name': 'João da Silva',
'idx_inflation_rate': '5%',
'salary': 'R$ 1.500,00',
'sender_name': 'Maria de Souza',
'sender_role': 'Gerente de RH',
}
tmpl_email = Template(tmpl_email)
print(tmpl_email.substitute(to_replace))
print(tmpl_email.safe_substitute(to_replace_two))
Como podemos notar ao instanciarmos o objeto Template passamos no construtor um modelo contendo a “marcação” de quais campos queremos interpolar, na implementação da classe podemos ver que essa “marcação” leva o nome de “delimiter” e que por padrão seu valor é $.
class Template:
"""A string class for supporting $-substitutions."""
delimiter = '$'
# r'[a-z]' matches to non-ASCII letters when used with IGNORECASE, but
# without the ASCII flag. We can't add re.ASCII to flags because of
# backward compatibility. So we use the ?a local flag and [a-z] pattern.
# See https://bugs.python.org/issue31672
idpattern = r'(?a:[_a-z][_a-z0-9]*)'
braceidpattern = None
flags = _re.IGNORECASE
Então na prática as strings que serão substituídas devem iniciar com o delimitador $, caso você não criei um classe personalizada para isso.
Agora falando em substituir existem dois métodos disponíveis para isso:
string.substitute()
string.safe_substitute()
O método substitute() irá lançar uma exceção do tipo KeyError caso algum campo não seja encontrado no objeto que você passou como parâmetro, veja o exemplo abaixo onde o campo sender_company não foi passado no objeto to_replace_two.
print(tmpl_email.substitute(to_replace_two))
#output
Traceback (most recent call last):
File "/home/python/app/src/template_string.py", line 52, in <module>
print(tmpl_email.substitute(to_replace_two))
File "/usr/local/lib/python3.10/string.py", line 121, in substitute
return self.pattern.sub(convert, self.template)
File "/usr/local/lib/python3.10/string.py", line 114, in convert
return str(mapping[named])
KeyError: 'sender_company'
Agora caso não queira esse comportamento você pode utilizar o método safe_substitute() que irá ignorar os campos que não forem encontrados no objeto passado como parâmetro, retornando a string original.
print(tmpl_email.safe_substitute(to_replace_two))
#output
...
...
...
Agradecemos sua dedicação e contribuição para a empresa. Reconhecemos que seu trabalho é fundamental
para o nosso sucesso contínuo, e a atualização salarial é uma forma de valorizarmos seus esforços.
Parabenizamos pelo seu desempenho e estamos ansiosos para continuar trabalhando juntos.
Atenciosamente,
Maria de Souza
Gerente de RH
$sender_company
Podemos inclusive usar com objetos mais complexos:
from string import Template
dados_cliente = {
"nome": "João da Silva",
"idade": 35,
"endereco": {
"rua": "Rua Principal",
"cidade": "São Paulo",
"estado": "SP"
},
"pedidos": ["Item 1", "Item 2", "Item 3"]
}
tmpl_string = """
Olá, $nome!
Agradecemos por sua compra recente. Abaixo estão os detalhes do seu pedido:
- Itens comprados:
$itens
- Endereço de entrega:
Rua: $endereco_rua
Cidade: $endereco_cidade
Estado: $endereco_estado
Atenciosamente,
Empresa XYZ
"""
tmpl = Template(tmpl_string)
formatted = tmpl.substitute(
nome=dados_cliente["nome"],
itens="\n ".join(dados_cliente["pedidos"]),
endereco_rua=dados_cliente["endereco"]["rua"],
endereco_cidade=dados_cliente["endereco"]["cidade"],
endereco_estado=dados_cliente["endereco"]["estado"]
)
print(formatted)
#output
Olá, João da Silva!
Agradecemos por sua compra recente. Abaixo estão os detalhes do seu pedido:
- Itens comprados:
Item 1
Item 2
Item 3
- Endereço de entrega:
Rua: Rua Principal
Cidade: São Paulo
Estado: SP
Atenciosamente,
Empresa XYZ
Template String com Classe Personalizada
E para finalizarmos quero mostrar como podemos utilizar uma classe personalizada para fazer a interpolação dos campos. Você pode fazer isso criando uma classe que herde de Template e sobrescreva o atributo delimiter, veja o exemplo abaixo:
from string import Template
class MyTemplate(Template):
delimiter = '%'
dados_cliente = {
"nome": "João da Silva",
"idade": 35,
"endereco": {
"rua": "Rua Principal",
"cidade": "São Paulo",
"estado": "SP"
},
"pedidos": ["Item 1", "Item 2", "Item 3"]
}
tmpl_string = """
Olá, %nome!
Agradecemos por sua compra recente. Abaixo estão os detalhes do seu pedido:
- Itens comprados:
%itens
- Endereço de entrega:
Rua: %endereco_rua
Cidade: %endereco_cidade
Estado: %endereco_estado
Atenciosamente,
Empresa XYZ
"""
tmpl = MyTemplate(tmpl_string)
formatted = tmpl.substitute(
nome=dados_cliente["nome"],
itens="\n ".join(dados_cliente["pedidos"]),
endereco_rua=dados_cliente["endereco"]["rua"],
endereco_cidade=dados_cliente["endereco"]["cidade"],
endereco_estado=dados_cliente["endereco"]["estado"]
)
print(formatted)
#output
Olá, João da Silva!
Agradecemos por sua compra recente. Abaixo estão os detalhes do seu pedido:
- Itens comprados:
Item 1
Item 2
Item 3
- Endereço de entrega:
Rua: Rua Principal
Cidade: São Paulo
Estado: SP
Atenciosamente,
Empresa XYZ
"""
Como pode ver esse é um recurso muito útil e inclusive muito utilizado em softwares que dão suporte a internacionalização i18n.
Por hoje é isso, espero que tenha gostado e até a próxima.
Fonte: https://docs.python.org/pt-br/3.10/library/string.html