动态导入模块中类的字符串名称的Python动态实例化

Jav*_* C. 157 python

在python中,我必须实例化某个类,知道它在字符串中的名称,但这个类"存在"一个动态导入的模块中.一个例子如下:

loader类脚本:

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
Run Code Online (Sandbox Code Playgroud)

一些动态加载的模块脚本:

class myName:
  # etc...
Run Code Online (Sandbox Code Playgroud)

我使用这种安排来使任何动态加载的模块在dyn-loaded-modules中遵循某些预定义的行为,由loader-class使用...

任何想法都表示赞赏.

Sve*_*ach 219

你可以使用getattr

getattr(module, class_name)
Run Code Online (Sandbox Code Playgroud)

访问课程.更完整的代码:

module = __import__(module_name)
class_ = getattr(module, class_name)
instance = class_()
Run Code Online (Sandbox Code Playgroud)

如前所述下面,我们可以使用导入库

import importlib
module = importlib.import_module(module_name)
class_ = getattr(module, class_name)
instance = class_()
Run Code Online (Sandbox Code Playgroud)

  • 如果有人遇到上面提到的导入方法Sven的问题,我发现我的代码使用以下方法更好[[importlib.import_module](http://docs.python.org/2/library/importlib.html#importlib. import_module).可以像:module = importlib.import_module(module_name)一样使用 (16认同)
  • `module = __import __(module,fromlist = [name])`只对我有用. (3认同)

Rég*_* B. 111

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()
Run Code Online (Sandbox Code Playgroud)

说明

您可能不希望使用__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'
Run Code Online (Sandbox Code Playgroud)

以下是python doc所说的内容__import__:

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

而是使用标准importlib模块按名称动态导入模块.有了getattr那么你可以通过它的名字实例化一个类:

import importlib
my_module = importlib.import_module("module.submodule")
MyClass = getattr(my_module, "MyClass")
instance = MyClass()
Run Code Online (Sandbox Code Playgroud)

你也可以这样写:

import importlib
module_name, class_name = "module.submodule.MyClass".rsplit(".", 1)
MyClass = getattr(importlib.import_module(module_name), class_name)
instance = MyClass()
Run Code Online (Sandbox Code Playgroud)

此代码在python≥2.7(包括python 3)中有效.

  • 标记为答案的选项对我不起作用(使用子模块),但是此答案有效。我认为这应该是答案,因为它是用于动态加载模块的更通用的解决方案。 (2认同)

AFo*_*lia 13

用于getattr从字符串中的名称获取属性.换句话说,将实例作为

instance = getattr(modul, class_name)()
Run Code Online (Sandbox Code Playgroud)


And*_*ovs 10

复制粘贴代码段:

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
Run Code Online (Sandbox Code Playgroud)


Xem*_*ema 9

人们可以简单地使用该pydoc.locate功能。

from pydoc import locate
my_class = locate("module.submodule.myclass")
instance = my_class()
Run Code Online (Sandbox Code Playgroud)


小智 7

如果你想从字符串导入类和方法,你应该这样做:

\n
dynamic_import \n\xe2\x94\x82   my_class.py\n\xe2\x94\x82      \n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80subfolder\n\xe2\x94\x82   \xe2\x94\x82   my_subfolder_module.py\n\xe2\x94\x82   \xe2\x94\x82\n
Run Code Online (Sandbox Code Playgroud)\n
\n

my_subfolder_module.py

\n
\n
 class MySubfolderClass():\n        def test_method(self):\n            print ("Hello World")\n
Run Code Online (Sandbox Code Playgroud)\n
\n

主要.py

\n
\n
import importlib \n  \nmodule = importlib.import_module('subfolder.my_subfolder_module')\nclass_ = getattr(module, "MySubfolderClass")\nmethod_instance = getattr(class_(),"test_method")\nmethod_instance()\n#it will output the result of the test method, which is "Hello World"\n
Run Code Online (Sandbox Code Playgroud)\n


Ahm*_*kki 5

如果要from foo.bar import foo2动态加载此句子,则应执行此操作

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

instance = foo2()
Run Code Online (Sandbox Code Playgroud)