Pythondynamic实例化从dynamic导入模块中的类的string名称

在python中,我必须实例化某个类,知道它的名字在一个string中,但是这个类“生活”在一个dynamic导入的模块中。 一个例子如下:

加载器类脚本:

import sys class loader: def __init__(self, module_name, class_name): # both args are strings try: __import__(module_name) modul = sys.modules[module_name] instance = modul.class_name() # obviously this doesn't works, here is my main problem! except ImportError: # manage import error 

一些dynamic加载的模块脚本:

 class myName: # etc... 

我使用这种安排,使得在dyn-loaded-modules中按照某些预定义的行为,由loader-class使用任何dynamic加载的模块。

任何想法都表示赞赏。

你可以使用getattr

 getattr(module, class_name) 

去上课。 更完整的代码:

 module = __import__(module_name) class_ = getattr(module, class_name) instance = class_() 

TL;博士

importlib.import_module导入模块,并用getattr加载你需要的类:

 # Standard import import importlib # Load "module.submodule.MyClass" MyClass = getattr(importlib.import_module("module.submodule"), "MyClass") # Instantiate the class (pass arguments to the constructor, if needed) instance = MyClass() 

说明

您可能不希望使用__import__按名称dynamic导入模块,因为它不允许导入子模块:

 >>> mod = __import__("os.path") >>> mod.join Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'module' object has no attribute 'join' 

这里是python文档关于__import__所说的内容:

注意:与importlib.import_module()不同,这是日常Python编程中不需要的高级函数。

相反,使用标准的importlib模块按名称dynamic导入模块。 使用getattr你可以通过它的名字实例化一个类:

 import importlib my_module = importlib.import_module("module.submodule") MyClass = getattr(my_module, "MyClass") instance = MyClass() 

你也可以写:

 import importlib module_name, class_name = "module.submodule.MyClass".rsplit(".", 1) MyClass = getattr(importlib.import_module(module_name), class_name) instance = MyClass() 

这段代码在python≥2.7(包括python 3)中是有效的。

使用getattr从string中的名称获取属性。 换句话说,获取实例

 instance = getattr(modul, class_name)() 

复制粘贴片段:

 def str_to_class(module_name, class_name) try: module_ = importlib.import_module(module_name) try: class_ = getattr(module_, class_name)() except AttributeError: logging.error('Class does not exist') except ImportError: logging.error('Module does not exist') return class_ or None 

如果你想from foo.bar import foo2这个句子来dynamic加载,你应该这样做

 foo = __import__("foo") bar = getattr(foo,"bar") foo2 = getattr(bar,"foo2") instance = foo2() 

从上面的例子中,我不能完全达到目的,但艾哈迈德让我最接近(谢谢)。 对于那些将来阅读这些内容的人来说,这里是为我工作的代码。

 def get_class(fully_qualified_path, module_name, class_name, *instantiation): """ Returns an instantiated class for the given string descriptors :param fully_qualified_path: The path to the module eg("Utilities.Printer") :param module_name: The module name eg("Printer") :param class_name: The class name eg("ScreenPrinter") :param instantiation: Any fields required to instantiate the class :return: An instance of the class """ p = __import__(fully_qualified_path) m = getattr(p, module_name) c = getattr(m, class_name) instance = c(*instantiation) return instance