10

可能重复:
Python 中的动态模块导入

可能是一个简单的问题!我需要遍历从设置文件传递的类列表(作为字符串)。类如下所示:

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',
)

我现在需要authenticate()在这些类中的每一个上调用该函数(当然,除非被注释掉)。我很高兴遍历列表,我只需要知道如何在我的 foreach 循环中将字符串转换为 Class 对象,以便我可以调用authenticate它的方法。是否有捷径可寻?

4

1 回答 1

42

您想使用模块来处理这样importlib模块加载,然后简单地使用getattr()来获取类。

例如,假设我有一个模块,somemodule.py其中包含类Test

import importlib

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

somemodule = importlib.import_module(module_name)

print(getattr(somemodule, class_name))

给我:

<class 'somemodule.Test'>

添加诸如包之类的东西很简单:

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

somemodule = importlib.import_module(module_name)

如果模块/包已经被导入,它不会导入它,所以你可以很高兴地做到这一点,而无需跟踪加载模块:

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)]

 

于 2012-05-27T11:39:32.697 回答