Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Muita gente que trabalha com Python já se deparou com a necessidade de transformar uma string, recebida por exemplo via input ou leitura de arquivo, em uma referência direta a uma classe definida no escopo atual. Apesar de parecer uma tarefa simples, ela esconde armadilhas que podem impactar desde a segurança até a manutenção do código.
---
Imagine que você tem um sistema onde o usuário pode informar o nome de uma classe, e seu código precisa instanciá-la ou checar sua existência. A questão é: como fazer essa conversão de forma segura e eficaz, sem abrir brechas ou depender de soluções frágeis?
A solução mais direta e, por vezes, tentadora, é usar funções como eval() ou globals(). Com eval(), por exemplo, dá para passar a string e obter a classe, se ela estiver no escopo global. Mas, aí, vem o alerta: eval é uma bomba-relógio de segurança. Executar uma string arbitrária pode permitir a execução de código malicioso, o que é um risco enorme em ambientes de produção. Sem esse critério, a solução pode parecer simples no começo e cara no suporte.
Alternativamente, usar globals() ou locals() para buscar a classe pelo nome é mais seguro, mas exige que a classe esteja no escopo do momento, o que nem sempre é garantido.
Suponha que temos uma classe definida:
class Foo:
pass
Se quisermos transformar a string 'Foo' em um objeto de classe, podemos fazer:
classe_nome = 'Foo'
# Uso de globals()
classe_obj = globals().get(classe_nome)
# Verificação
if classe_obj:
instancia = classe_obj()
print(instancia)
else:
print(f'Classe {classe_nome} não encontrada.')
Este método é mais seguro, porém dependente do escopo.
globals() ou locals() podem impactar a performance.1. Validar o nome recebido, garantindo que corresponde a uma lista de nomes permitidos.
2. Manter um registry ou dicionário com os nomes das classes e suas referências.
3. Usar esse registry para resolver o nome em uma classe, sem usar eval().
Por exemplo:
registry = {
'Foo': Foo,
'Bar': Bar
}
def str_to_class(nome):
return registry.get(nome)
Assim, o controle é maior, e o risco de execução de código malicioso é eliminado. Esse contexto ajuda a separar ganho real de novidade difícil de sustentar. A decisão fica mais saudável quando o time consegue medir o impacto depois. Sem esse critério, a solução pode parecer simples no começo e cara no suporte. O valor aparece melhor quando operação, produto e engenharia olham para o mesmo risco. Por isso, o recorte precisa considerar manutenção, validação e caminho de volta. Esse contexto ajuda a separar ganho real de novidade difícil de sustentar.
---
A questão central é balancear segurança e flexibilidade. Em sistemas de alta segurança, prefira sempre um registry controlado. Quando a flexibilidade é prioridade, avalie bem os riscos de usar eval e pense em alternativas de validação e cache. A decisão fica mais saudável quando o time consegue medir o impacto depois. Sem esse critério, a solução pode parecer simples no começo e cara no suporte. O valor aparece melhor quando operação, produto e engenharia olham para o mesmo risco. Por isso, o recorte precisa considerar manutenção, validação e caminho de volta. Esse contexto ajuda a separar ganho real de novidade difícil de sustentar.
No seu time, já passaram por alguma situação parecida? Como vocês resolveram o problema de forma prática e segura? Sem esse critério, a solução pode parecer simples no começo e cara no suporte. O vaalor aparece melhor quando operação, produto e engenharia olham para o mesmo risco. Por isso, o recorte precisa considerar manutenção, validação e caminho de volta. Esse contexto ajuda a separar ganho real de novidade difícil de sustentar. A decisão fica mais saudável quando o time consegue medir o impacto depois. Sem esse critério, a solução pode parecer simples no começo e cara no suporte. O valor aparece melhor quando operação, produto e engenharia olham para o mesmo risco.
Exato, Leandro. Já vi gente confiar demais no eval e sofrer as consequências. Um registry bem organizado ajuda bastante.
resolveu lindamente
Boa, mas acho que o maior desafio é cuidar para que o nome recebido seja válido antes de fazer qualquer coisa. Você costuma usar alguma lista de nomes permitidos?
No meu time, evitamos eval ao máximo. Criamos uma lista de classes permitidas e acessamos via dicionário. Assim, o risco de execuçãão de código malicioso cai pra zero.
Isso me ajuda bastante. Ainda tenho receio de deixar tudo na mão do usuário, mas com validação fica mais tranquilo. Já tiveram problemas com nomes de classes que mudaram?