Detailed explanation of using code to dynamically create class instances in Python

高洛峰
Release: 2017-03-26 10:07:53
Original
1724 people have browsed it

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
Copy after login

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'
Copy after login

my_another_module.py


class MyAnotherObject(object):
  def test(self):
    print 'MyAnotherObject.test'
Copy after login

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
Copy after login

pyinstaller integration

For applications packaged with pyinstaller, if you use the above code, the following error will occur when running the packaged program


Traceback (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
Copy after login

The reason for the error here is that pyinstaller did not analyze the modules under my_modules when packaging the analysis class, so an error was reported when running.

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()
Copy after login

Solution 2:

When using pyinstaller to package, specify "--hidden- import", as follows


pyinstaller -D --hidden-import my_modules.my_module test.py
Copy after login

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()
Copy after login

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!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template