Dada uma string como entrada do usuário para uma função Python, eu gostaria de obter um objeto de classe, se houver uma classe com esse nome no espaço para nome definido atualmente. Essencialmente, quero a implementação de uma função que produza esse tipo de resultado:
class Foo:
pass
str_to_class("Foo")
==> <class __main__.Foo at 0x69ba0>
Tudo isso é possível?
Respostas:
Isso parece mais simples.
fonte
Isso poderia funcionar:
fonte
def str_to_class(str): return vars()[str]
?Você poderia fazer algo como:
fonte
globals()
... outra coisa que deve ser evitadaglobals()
é sem dúvida muito menos ruim do queeval
e realmente não é pior do que osys.modules[__name__]
AFAIK.Você quer a classe
Baz
, que vive no módulofoo.bar
. Com o Python 2.7, você deseja usarimportlib.import_module()
, pois isso facilitará a transição para o Python 3:Com Python <2.7:
Usar:
fonte
Isso manipula com precisão as classes de estilo antigo e novo.
fonte
Eu olhei como o django lida com isso
django.utils.module_loading tem isso
Você pode usá-lo como
import_string("module_path.to.all.the.way.to.your_class")
fonte
Sim, você pode fazer isso. Supondo que suas classes existam no espaço de nomes global, algo como isso fará isso:
fonte
Em termos de execução arbitrária de código ou nomes indesejados de usuários, você pode ter uma lista de nomes de funções / classes aceitáveis e, se a entrada corresponder a uma da lista, ela será avaliada.
PS: Eu sei ... meio atrasado ... mas é para quem mais se deparar com isso no futuro.
fonte
Usar importlib funcionou melhor para mim.
Isso usa a notação de ponto de cadeia para o módulo python que você deseja importar.
fonte
Se você realmente deseja recuperar as classes criadas com uma string, deve armazenar (ou corretamente redigido, referência las ) em um dicionário. Afinal, isso também permitirá nomear suas classes em um nível superior e evitar a exposição de classes indesejadas.
Por exemplo, em um jogo em que classes de ator são definidas em Python e você deseja evitar que outras classes gerais sejam alcançadas pela entrada do usuário.
Outra abordagem (como no exemplo abaixo) seria criar uma nova classe inteira, que contém o que foi dito
dict
acima. Isso seria:Exemplo:
Isso me retorna:
Outro experimento divertido a ver com isso é adicionar um método que atenda às suas necessidades,
ClassHolder
para que você nunca perca todas as aulas que fez: ^)fonte