2012-05-27 12 views
9

Powiel możliwe:
Dynamic module import in PythonGet Pythona klasy obiektu z ciągiem

Prawdopodobnie proste pytanie! Potrzebuję do iteracji poprzez listę klas (jako ciągi) przekazywane z pliku ustawień. Klasy są wymienione jak poniżej:

TWO_FACTOR_BACKENDS = (
    'id.backends.AllowToBeDisabled', # Disable this to enforce Two Factor Authentication 
    'id.backends.TOTPBackend', 
    'id.backends.HOTPBackend', 
    #'id.backends.YubikeyBackend', 
    #'id.backends.OneTimePadBackend', 
    #'id.backends.EmailBackend', 
) 

Teraz trzeba wywołać funkcję authenticate() w każdej z tych klas (o ile nie wypowiedziało się, oczywiście). Z przyjemnością przeglądam listę, po prostu muszę wiedzieć, jak przekonwertować łańcuchy na obiekt klasy w mojej pętli foreach, aby móc wywołać na nim metodę authenticate. Czy istnieje prosty sposób na zrobienie tego?

+0

Chcesz 'authenticate()' nazwie na zajęciach, albo na obiektach tych klas? – robert

+0

Niestety, 'authenticate()' jest wywoływane na klasach, a nie obiektach klas. Powinno to sprawić, że bardziej zrozumiale przepraszam! –

Odpowiedz

34

Chcesz użyć the importlib module do obsługi ładowania takich modułów, a następnie po prostu użyj getattr(), aby uzyskać klasy.

Na przykład, że mam moduł, somemodule.py który zawiera klasę Test:

import importlib 

cls = "somemodule.Test" 
module_name, class_name = cls.split(".") 

somemodule = importlib.import_module(module_name) 

print(getattr(somemodule, class_name)) 

daje mi:

<class 'somemodule.Test'> 

To trywialne dodać w takie rzeczy jak pakietach:

cls = "test.somemodule.Test" 
module_name, class_name = cls.rsplit(".", 1) 

somemodule = importlib.import_module(module_name) 

I nie zaimportuje modułu/pakietu, jeśli już był rted, więc można to zrobić bez szczęśliwie śledzenie ładowania modułów:

import importlib 

TWO_FACTOR_BACKENDS = (
    'id.backends.AllowToBeDisabled', # Disable this to enforce Two Factor Authentication 
    'id.backends.TOTPBackend', 
    'id.backends.HOTPBackend', 
    #'id.backends.YubikeyBackend', 
    #'id.backends.OneTimePadBackend', 
    #'id.backends.EmailBackend', 
) 

backends = [getattr(importlib.import_module(mod), cls) for (mod, cls) in (backend.rsplit(".", 1) for backend in TWO_FACTOR_BACKENDS)] 

Powiązane problemy