问题:从动态导入的模块中的类的字符串名称动态实例化?
在python中,我必须实例化某些类,知道它在字符串中的名称,但是该类“存在”于动态导入的模块中。下面是一个示例:
加载程序类脚本:
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
一些动态加载的模块脚本:
class myName:
# etc...
我使用这种安排使dyn-loaded-modules中的某些预定义行为使加载程序类使用任何动态加载的模块…
回答 0
您可以使用getattr
getattr(module, class_name)
访问类。更完整的代码:
module = __import__(module_name)
class_ = getattr(module, class_name)
instance = class_()
如前所述下面,我们可以使用导入库
import importlib
module = importlib.import_module(module_name)
class_ = getattr(module, class_name)
instance = class_()
回答 1
tl; dr
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__
按名称动态导入模块,因为它不允许您导入子模块:
>>> 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__
:
注意:这是日常Python编程中不需要的高级功能,与importlib.import_module()不同。
而是使用标准importlib
模块按名称动态导入模块。有了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)中有效。
回答 2
用于getattr
从字符串中的名称获取属性。换句话说,将实例获取为
instance = getattr(modul, class_name)()
回答 3
复制粘贴代码段:
import importlib
def str_to_class(module_name, class_name):
"""Return a class instance from a string reference"""
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
回答 4
如果要from foo.bar import foo2
动态加载此句子,则应执行此操作
foo = __import__("foo")
bar = getattr(foo,"bar")
foo2 = getattr(bar,"foo2")
instance = foo2()
回答 5
一个人可以简单地使用该pydoc.locate
功能。
from pydoc import locate
my_class = locate("module.submodule.myclass")
instance = my_class()
回答 6
在上面的示例中,我无法完全达到用例的目的,但是艾哈迈德让我最接近了(谢谢)。对于以后阅读此书的人来说,以下是对我有用的代码。
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
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。