使用locate动态实例化类

问题描述 投票:1回答:1

我试图从一个字符串动态地实例化一个类,该字符串被提供给一个方法。

from pydoc import locate
name = "folder.subfolder.classname"
my_class = locate(name)
instance = my_class()

这样做会导致错误:

TypeError: 'module' object is not callable

我的问题是:我怎样才能知道我需要打哪个班级?如果我硬编码值并做my_class.classname()我可以实例化它,但我希望最后一部分是动态的,而不是硬编码。我怎样才能做到这一点?

python python-3.x reflection
1个回答
2
投票

编辑2:

该解决方案将收集用户提供的模块中可用的所有类,然后简单地实例化第一个类。

import inspect
from pydoc import locate
name = "folder.subfolder.classname"
my_module = locate(name)

all_classes = inspect.getmembers(my_module, inspect.isclass)
if len(all_classes) > 0:
    instance = all_classes[0][1]()

编辑:

从评论中收集我相信以下代码将适用于您的用例:

from pydoc import locate
name = "folder.subfolder.classname"
my_module = locate(name)
class_name = name.rsplit('.')[-1]
my_class = getattr(my_module, class_name)
instance = my_class()

您似乎对哪些模块导致我们的错误传达感到有点困惑。 class.py不指向类,而是指向模块。在该模块(您的class.py文件)中可以有多个类。对于上面的答案,我假设你的class.py文件中有一个与文件同名的类。

原答案:

正如您的错误所示,您的my_class变量实际上是一个模块对象。您提供的名称实际上并不指向您的类,而是指向包含该类的模块。

要按字符串从模块对象获取类,您可以执行以下操作:

my_class = getattr(module, class_name)

然后在您的示例代码中,您可以像这样实例化它:

instance = my_class()

把它们放在一起:

module_name = "folder.subfolder.module_name"
my_module = locate(module_name)
my_class = getattr(my_module, class_name)
instance = my_class()
© www.soinside.com 2019 - 2024. All rights reserved.