Biorąc pod uwagę ciąg znaków wprowadzany przez użytkownika do funkcji Python, chciałbym wyciągnąć z niego obiekt klasy, jeśli istnieje klasa o tej nazwie w aktualnie zdefiniowanej przestrzeni nazw. Zasadniczo chcę implementacji funkcji, która da taki wynik:
class Foo:
pass
str_to_class("Foo")
==> <class __main__.Foo at 0x69ba0>
Czy to w ogóle jest możliwe?
Odpowiedzi:
To wydaje się najprostsze.
źródło
To może działać:
źródło
def str_to_class(str): return vars()[str]
?Możesz zrobić coś takiego:
źródło
globals()
... innej rzeczy, której należy unikaćglobals()
jest prawdopodobnie znacznie mniej zły niżeval
i wcale nie gorszy niżsys.modules[__name__]
AFAIK.Chcesz klasy
Baz
, która mieszka w modulefoo.bar
. Z Python 2.7 chcesz korzystaćimportlib.import_module()
, ponieważ ułatwi to przejście do Python 3:Z Pythonem <2.7:
Posługiwać się:
źródło
To dokładnie obsługuje zarówno klasy w starym, jak i nowym stylu.
źródło
Patrzyłem, jak django sobie z tym radzi
django.utils.module_loading ma to
Możesz go używać jak
import_string("module_path.to.all.the.way.to.your_class")
źródło
Tak, możesz to zrobić. Zakładając, że twoje klasy istnieją w globalnej przestrzeni nazw, coś takiego to zrobi:
źródło
Jeśli chodzi o wykonanie dowolnego kodu lub niepotrzebne nazwy użytkowników, możesz mieć listę akceptowalnych nazw funkcji / klas, a jeśli dane wejściowe pasują do jednej na liście, są ewaluowane.
PS: Wiem ... trochę późno ... ale to dla każdego, kto natknie się na to w przyszłości.
źródło
Korzystanie z importlib działało dla mnie najlepiej.
Używa to notacji ciąg kropkowej dla modułu python, który chcesz zaimportować.
źródło
Jeśli naprawdę chcesz odzyskać klasy, które tworzysz za pomocą łańcucha, powinieneś przechowywać je (lub odpowiednio sformułować, odwoływać się ) w słowniku. W końcu pozwoli to także nazwać swoje klasy na wyższym poziomie i uniknąć ujawniania niepożądanych klas.
Przykład: z gry, w której klasy aktorskie są zdefiniowane w Pythonie i chcesz uniknąć innych klas ogólnych, do których dostęp miałby użytkownik.
Inne podejście (jak w poniższym przykładzie) stworzyłoby całą nową klasę, która zawiera
dict
powyższe. To by:Przykład:
To zwraca mi:
Kolejnym zabawnym eksperymentem związanym z tymi jest dodanie metody, która pikluje
ClassHolder
, abyś nigdy nie stracił wszystkich zajęć: ^)źródło