Python中动态创建类实例的方法


Posted in Python onMarch 24, 2017

简介

在Java中我们可以通过反射来根据类名创建类实例,那么在Python我们怎么实现类似功能呢?

其实在Python有一个builtin函数import,我们可以使用这个函数来在运行时动态加载一些模块。如下:

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

例子

首先我们建一个目录 my_modules,其中包括三个文件

* init.py: 模块文件
* my_module.py: 测试用的模块
* my_another_module: 另一个测试用的模块

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集成

对于使用pyinstaller打包的应用程序,如果使用上面的代码,运行打包后的程序会出现下面的错误

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

这里错误的原因是 pyinstaller 在打包分析类的时候没有分析到 my_modules 下面的模块,所以运行报错。

解决办法一:

在 test.py 中把 my_modules 下的模块手动 import,见下面代码中的第一行。这种方法最简单,但是显然不太好。

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()

解决办法二:

在使用 pyinstaller 打包的时候,指定 “?hidden-import”,如下

pyinstaller -D --hidden-import my_modules.my_module test.py

解决办法三:

动态修改 python 运行时path,见下面代码中的前两行,其中path我们可以通过环境变量或者参数传递进来。显然这种方法要比前两种方法灵活的多。

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()

以上所述是小编给大家介绍的Python中动态创建类实例的方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Python 相关文章推荐
python中元类用法实例
Oct 10 Python
Python实现模拟登录及表单提交的方法
Jul 25 Python
Python使用正则表达式过滤或替换HTML标签的方法详解
Sep 25 Python
Python使用SQLite和Excel操作进行数据分析
Jan 20 Python
python实现Decorator模式实例代码
Feb 09 Python
Python实现自定义函数的5种常见形式分析
Jun 16 Python
Python基于pandas实现json格式转换成dataframe的方法
Jun 22 Python
python的xpath获取div标签内html内容,实现innerhtml功能的方法
Jan 02 Python
python lxml中etree的简单应用
May 10 Python
python 并发编程 非阻塞IO模型原理解析
Aug 20 Python
Python 3.8正式发布重要新功能一览
Oct 17 Python
Python实现word2Vec model过程解析
Dec 16 Python
python3中set(集合)的语法总结分享
Mar 24 #Python
Python Socket编程详细介绍
Mar 23 #Python
python3中int(整型)的使用教程
Mar 23 #Python
python利用Guetzli批量压缩图片
Mar 23 #Python
python3中str(字符串)的使用教程
Mar 23 #Python
python常用知识梳理(必看篇)
Mar 23 #Python
Python爬取qq music中的音乐url及批量下载
Mar 23 #Python
You might like
PHP实现抓取迅雷VIP账号的方法
2015/07/30 PHP
PHP使用函数用法详解
2018/09/30 PHP
PDO::errorCode讲解
2019/01/28 PHP
PHP实现的文件浏览器功能简单示例
2019/09/12 PHP
初试jQuery EasyUI 使用介绍
2010/04/01 Javascript
Extjs改变树节点的勾选状态点击按钮将复选框去掉
2013/11/14 Javascript
IE与FF下javascript获取网页及窗口大小的区别详解
2014/01/14 Javascript
node.js中的fs.link方法使用说明
2014/12/15 Javascript
使用命令对象代替switch语句的写法示例
2015/02/28 Javascript
ArtEditor富文本编辑器增加表单提交功能
2016/04/18 Javascript
jQuery实现的可编辑表格完整实例
2016/06/20 Javascript
JavaScript 数组- Array的方法总结(推荐)
2016/07/21 Javascript
浅谈js继承的实现及公有、私有、静态方法的书写
2016/10/28 Javascript
jQuery插件HighCharts实现的2D条状图效果示例【附demo源码下载】
2017/03/15 Javascript
详解weex默认webpack.config.js改造
2018/01/08 Javascript
微信小程序 textarea 层级过高问题简单解决方案
2019/10/14 Javascript
[44:51]2018DOTA2亚洲邀请赛 4.4 淘汰赛 VP vs Liquid 第二场
2018/04/05 DOTA
[45:14]Optic vs VP 2018国际邀请赛淘汰赛BO3 第二场 8.24
2018/08/25 DOTA
用Python从零实现贝叶斯分类器的机器学习的教程
2015/03/31 Python
Python文件右键找不到IDLE打开项解决办法
2015/06/08 Python
Python解析树及树的遍历
2016/02/03 Python
Python设置默认编码为utf8的方法
2016/07/01 Python
django model去掉unique_together报错的解决方案
2016/10/18 Python
python字符串str和字节数组相互转化方法
2017/03/18 Python
详解python异步编程之asyncio(百万并发)
2018/07/07 Python
对python自动生成接口测试的示例讲解
2018/11/30 Python
python实现输入的数据在地图上生成热力图效果
2019/12/06 Python
使用python客户端访问impala的操作方式
2020/03/28 Python
Python中使用socks5设置全局代理的方法示例
2020/04/15 Python
python输出国际象棋棋盘的实例分享
2020/11/26 Python
什么是聚集索引和非聚集索引
2012/01/17 面试题
StringBuilder和String的区别
2015/05/18 面试题
洗手间标语
2014/06/23 职场文书
爱护草坪标语
2014/06/24 职场文书
数学教师个人工作总结
2015/02/06 职场文书
唤醒紫霞仙子,携手再游三界!大话手游X《大话西游》电影合作专属剧情任务
2022/04/03 其他游戏