In Java we can create class instances based on class names through reflection, so how do we achieve similar functions in Python? In fact, there is a builtin function import in Python. We can use this function to dynamically load some modules at runtime
Introduction
In Java We can create class instances based on class names through reflection, so how do we achieve similar functions in Python?
In fact, there is a builtin function import in Python. We can use this function to dynamically load some modules at runtime. As follows:
def createInstance(module_name, class_name, *args, **kwargs): module_meta = __import__(module_name, globals(), locals(), [class_name]) class_meta = getattr(module_meta, class_name) obj = class_meta(*args, **kwargs) return obj
Example
First we create a directory my_modules, which includes three files
* init.py: module file
* my_module.py: module for testing
* my_another_module: another module for testing
my_module.py
# #
from my_modules.my_another_module import * class MyObject(object): def test(self): print 'MyObject.test' MyObject1().test() MyObject2().test() MyAnotherObject().test() class MyObject1(object): def test(self): print 'MyObject1.test' class MyObject2(object): def test(self): print 'MyObject2.test'
my_another_module.py
class MyAnotherObject(object): def test(self): print 'MyAnotherObject.test'
test.py
def createInstance(module_name, class_name, *args, **kwargs): module_meta = __import__(module_name, globals(), locals(), [class_name]) class_meta = getattr(module_meta, class_name) obj = class_meta(*args, **kwargs) return obj obj = createInstance("my_modules.my_module", "MyObject") obj.test() MyObject.test MyObject1.test MyObject2.test MyAnotherObject.test
pyinstaller integration
For applications packaged with pyinstaller, if you use the above code, the following error will occur when running the packaged programTraceback (most recent call last): File "test.py", line 12, in <module> obj = createInstance("my_modules.my_module", "MyObject") File "test.py", line 7, in createInstance module_meta = __import__(module_name, globals(), locals(), [class_name]) ImportError: No module named my_modules.my_module Failed to execute script test
Solution 1:
Manually import the module under my_modules in test.py, see the first line of the code below. This method is the simplest, but obviously not very good.import my_modules.my_module def createInstance(module_name, class_name, *args, **kwargs): module_meta = __import__(module_name, globals(), locals(), [class_name]) class_meta = getattr(module_meta, class_name) obj = class_meta(*args, **kwargs) return obj obj = createInstance("my_modules.my_module", "MyObject") obj.test()
Solution 2:
When using pyinstaller to package, specify "--hidden- import", as followspyinstaller -D --hidden-import my_modules.my_module test.py
Solution three:
Dynamicly modify the python runtime path, see In the first two lines of the code below, we can pass path in through environment variables or parameters. Obviously this method is much more flexible than the first two methods.import sys sys.path.append(...) def createInstance(module_name, class_name, *args, **kwargs): module_meta = __import__(module_name, globals(), locals(), [class_name]) class_meta = getattr(module_meta, class_name) obj = class_meta(*args, **kwargs) return obj obj = createInstance("my_modules.my_module", "MyObject") obj.test()
The above is the detailed content of Detailed explanation of using code to dynamically create class instances in Python. For more information, please follow other related articles on the PHP Chinese website!