Biorąc pod uwagę ciąg klasy Pythona, np. my_package.my_module.MyClass
Jaki jest najlepszy możliwy sposób jej załadowania?
Innymi słowy szukam odpowiednika Class.forName()
w Javie, funkcji w Pythonie. Musi działać w Google App Engine.
Najlepiej byłoby, gdyby była to funkcja, która akceptuje FQN klasy jako ciąg i zwraca odniesienie do klasy:
my_class = load_class('my_package.my_module.MyClass')
my_instance = my_class()
python
reflection
python-import
pjesi
źródło
źródło
Odpowiedzi:
Z dokumentacji Pythona, oto funkcja, której potrzebujesz:
Powodem, dla którego proste
__import__
nie zadziała, jest to, że jakikolwiek import czegokolwiek poza pierwszą kropką w ciągu pakietu jest atrybutem importowanego modułu. Tak więc coś takiego nie zadziała:Musiałbyś wywołać powyższą funkcję w ten sposób:
Lub w Twoim przykładzie:
EDYCJA : Trochę mnie to obchodziło. Zasadniczo chcesz to zrobić:
Powyższa funkcja jest konieczna tylko wtedy, gdy masz pustą listę fromlist. Zatem odpowiednie wywołanie wyglądałoby tak:
źródło
Jeśli nie chcesz tworzyć własnych, w
pydoc
module dostępna jest funkcja , która robi dokładnie to:Zaletą tego podejścia w porównaniu z innymi wymienionymi tutaj jest to, że
locate
znajdzie dowolny obiekt Pythona w podanej kropkowanej ścieżce, a nie tylko obiekt bezpośrednio w module. npmy_package.my_module.MyClass.attr
.Jeśli jesteś ciekawy, jaki jest ich przepis, oto funkcja:
Opiera się na
pydoc.safeimport
funkcji. Oto dokumenty dotyczące tego:źródło
qualname
poprawnie obsłużyć (obiekt nie znajduje się na górze przestrzeni nazw modułu).locate('my_package.my_module.MyClass.attr.method.etc')
źródło
źródło
(modulename, classname) = cl.rsplit('.', 2)
rsplit('.', 1)
?Jeśli używasz Django, możesz tego użyć. Tak, zdaję sobie sprawę, że OP nie pytał o django, ale natknąłem się na to pytanie szukając rozwiązania Django, nie znalazłem go i umieściłem tutaj dla następnego chłopca / dziewczyny, który go szuka.
Pamiętaj, że jeśli chcesz zaimportować coś, co nie ma znaku
.
, likere
aniargparse
:źródło
Tutaj jest coś, co znalazłem na
__import__
iimportlib
próbując rozwiązać ten problem.Używam Pythona 3.7.3.
Kiedy próbuję dostać się do zajęć
d
w modulea.b.c
,mod
Zmienna odnosi się do górnej przestrzeni nazwa
.Więc żeby dostać się do klasy
d
, muszęJeśli spróbujemy
faktycznie staramy się szukać
a.d
.Kiedy używam
importlib
, przypuszczam, że biblioteka wykonałagetattr
za nas rekurencję . Tak więc, kiedy używamyimportlib.import_module
, faktycznie otrzymujemy uchwyt na najgłębszy moduł.źródło
OK, dla mnie tak to działało (używam Pythona 2.7):
Wtedy b jest instancją klasy „MyClass”
źródło
Jeśli masz już instancję żądanej klasy, możesz użyć funkcji 'type', aby wyodrębnić jej typ klasy i użyć tego do skonstruowania nowej instancji:
źródło
źródło
W Google App Engine istnieje
webapp2
funkcja o nazwieimport_string
. Więcej informacji można znaleźć tutaj: https://webapp-improved.appspot.com/api/webapp2.htmlWięc,
Na przykład jest to używane w miejscu, w
webapp2.Route
którym można użyć procedury obsługi lub ciągu.źródło