Dynamic instantiation from string name of a class in dynamically imported module?
You can use getattr
getattr(module, class_name)
to access the class. More complete code:
module = __import__(module_name)
class_ = getattr(module, class_name)
instance = class_()
As mentioned below, we may use importlib
import importlib
module = importlib.import_module(module_name)
class_ = getattr(module, class_name)
instance = class_()
Copy-paste snippet:
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
tl;dr
Import the root module with importlib.import_module
and load the class by its name using getattr
function:
# 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()
explanations
You probably don't want to use __import__
to dynamically import a module by name, as it does not allow you to import submodules:
>>> mod = __import__("os.path")
>>> mod.join
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'join'
Here is what the python doc says about __import__
:
Note: This is an advanced function that is not needed in everyday Python programming, unlike importlib.import_module().
Instead, use the standard importlib
module to dynamically import a module by name. With getattr
you can then instantiate a class by its name:
import importlib
my_module = importlib.import_module("module.submodule")
MyClass = getattr(my_module, "MyClass")
instance = MyClass()
You could also write:
import importlib
module_name, class_name = "module.submodule.MyClass".rsplit(".", 1)
MyClass = getattr(importlib.import_module(module_name), class_name)
instance = MyClass()
This code is valid in python ≥ 2.7 (including python 3).