Python重新加载模块的实现方法


Posted in Python onOctober 16, 2018

importlib 模块的作用

模块,是一个一个单独的py文件 包,里面包含多个模块(py文件)

动态导入模块,这样就不用写那么多的import代码, 典型的例子: 自动同步服务,每个网站都有一个py文件。主进程里收到同步任务,根据名称来动态导入对应的py文件,这样就不用写那么多的import代码。(有点类似java的工厂方法)

但是,importlib并不能解决我在线修改py源码,再不重启进程的情况下,使修改生效。 这种情况,可以使用reload()

reload方法

为防止两个模块互相导入的问题,Python默认所有的模块都只导入一次,如果需要重新导入模块, Python2.7可以直接用reload(),Python3可以用下面几种方法:

方法一:基本方法 from imp import reload reload(module)

方法二:按照套路,可以这样 import imp imp.reload(module)

方法三:看看imp.py,有发现,所以还可以这样 import importlib importlib.reload(module)

方法四:根据天理,当然也可以这样 from importlib import reload reload(module)

在多进程的 程序中,一个进程的reload是无法影响另一个进程的

例子:

# 在主进程中启动多进程
def begin():
  """ 启动多进程 """
  plist = []
  for i in xrange(Num_process):
    p = Process(target=pre_run)
    p.start()
    plist.append(p)
  # 此进程监听redis消息,收到消息,即执行reload方法
  p = Process(target=reload_spider)
  p.start()
  plist.append(p)
  for p in plist:
    p.join()
# 监听redis,执行reload方法
def reload_spider():
  """ 监听文件变化,自动reload """
  rconn = redis.Redis(host=settings.REDIS_HOST, port=settings.REDIS_PORT, db=settings.REDIS_DB, password=settings.REDIS_PW)
  while True:
    try:
      key = 'reload-spider'
      value = rconn.get(key)
      print value
      if value == '1':
        crawler_module = importlib.import_module('crawlers.%s' % 'temp'.lower())
        reload(crawler_module)
        crawlerClass = getattr(crawler_module, 'temp'.upper())
        print 'reload_spider 中的class: %s' % (crawlerClass.name)
      # rconn.delete(key)
    except Exception, e:
      pass
    time.sleep(3)

另一个进程打印py文件里面一个变量

crawler = get_crawler_from_factory(mq_service, message)
  print crawler.name

结果发现,一个进程中进行了reload,并不能改变另外一个进程中的变量。那么在同一个进程中呢...

同一进程中,多线程,任一线程进行了reload操作,其他线程均受影响

def pre_run():
  t = threading.Thread(target=reload_spider, name='LoopThread')
  t.start()
  # t.join()
 
  """ 在每个进程里面再使用多线程 """
  pool = ThreadPool(Num_Thread)
  # 初始化mq通道
  mq_service = RabbitMqService()
 
  def callback(ch, method, properties, body):
    # 消息确认
    mq_service.input_channel.basic_ack(delivery_tag=method.delivery_tag)
    # 获取当前线程的名字
    current_process_name = multiprocessing.current_process().name
    logger.debug('当前进程名称:%s - pid: %s' % (current_process_name, os.getpid()))
    logger.debug('进程 %s,收到消息: %s' % (current_process_name, body))
    # 收到任务消息,丢给线程池处理
    pool.apply_async(run, (properties, body, mq_service))
  # 开始监听入口通道
  mq_service.receive(callback)

reload_spider中监听redi中的消息,如果有reload标识,进行reload操作

def reload_spider():
  """ 监听文件变化,自动reload """
  rconn = redis.Redis(host=settings.REDIS_HOST, port=settings.REDIS_PORT, db=settings.REDIS_DB, password=settings.REDIS_PW)
  while True:
    try:
      key = 'reload-spider'
      value = rconn.get(key)
      print value
      if value == '1':
        crawler_module = importlib.import_module('crawlers.%s' % 'temp'.lower())
        reload(crawler_module)
        crawlerClass = getattr(crawler_module, 'temp'.upper())
        print 'reload_spider 中的class: %s' % (crawlerClass.name)
      # rconn.delete(key)
    except Exception, e:
      pass
    time.sleep(3)

经测试,其他线程中的引入的变量,也改变了。

当然,消息监听最好使用mq或者是redis阻塞队列

以上这篇Python重新加载模块的实现方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python同时给两个收件人发送邮件的方法
Apr 30 Python
python3.4用循环往mysql5.7中写数据并输出的实现方法
Jun 20 Python
Python基于Pymssql模块实现连接SQL Server数据库的方法详解
Jul 20 Python
Python实现在线暴力破解邮箱账号密码功能示例【测试可用】
Sep 06 Python
Python运维开发之psutil库的使用详解
Oct 18 Python
python调用虹软2.0第三版的具体使用
Feb 22 Python
Python 中判断列表是否为空的方法
Nov 24 Python
python解析多层json操作示例
Dec 30 Python
python不使用for计算两组、多个矩形两两间的iou方式
Jan 18 Python
python安装dlib库报错问题及解决方法
Mar 16 Python
python urllib和urllib3知识点总结
Feb 08 Python
Python自动操作神器PyAutoGUI的使用教程
Jun 16 Python
django Serializer序列化使用方法详解
Oct 16 #Python
为什么str(float)在Python 3中比Python 2返回更多的数字
Oct 16 #Python
对python添加模块路径的三种方法总结
Oct 16 #Python
Python中的CSV文件使用"with"语句的方式详解
Oct 16 #Python
详解django的serializer序列化model几种方法
Oct 16 #Python
Python调用C++,通过Pybind11制作Python接口
Oct 16 #Python
Python之inspect模块实现获取加载模块路径的方法
Oct 16 #Python
You might like
一些被忽视的PHP函数(简单整理)
2010/04/30 PHP
PHP正则表达式之定界符和原子介绍
2012/10/05 PHP
利用phpexcel把excel导入数据库和数据库导出excel实现
2014/01/09 PHP
如何利用http协议发布博客园博文评论
2015/08/03 PHP
PHP时间函数使用详解
2019/03/21 PHP
Js 去掉字符串中的空格(实现代码)
2013/11/19 Javascript
jQuery 删除/替换DOM元素的几种方式
2014/05/20 Javascript
jQuery的one()方法用法实例
2015/01/19 Javascript
DOM 高级编程
2015/05/06 Javascript
jquery实现适用于门户站的导航下拉菜单效果代码
2015/08/24 Javascript
基于jQuery实现滚动刷新效果
2017/01/09 Javascript
Express之get,pos请求参数的获取
2017/05/02 Javascript
vue-cli webpack模板项目搭建及打包时路径问题的解决方法
2018/02/26 Javascript
Vue列表渲染的示例代码
2018/11/01 Javascript
详解vue路由篇(动态路由、路由嵌套)
2019/01/27 Javascript
微信小程序实现左侧滑动导航栏
2020/04/08 Javascript
vue 解决data中定义图片相对路径页面不显示的问题
2020/08/13 Javascript
Vue实现小购物车功能
2020/12/21 Vue.js
简单介绍Python中用于求最小值的min()方法
2015/05/15 Python
python 开发的三种运行模式详细介绍
2017/01/18 Python
python3中bytes和string之间的互相转换
2017/02/09 Python
Python 实现简单的shell sed替换功能(实例讲解)
2017/09/29 Python
Python中的heapq模块源码详析
2019/01/08 Python
django的csrf实现过程详解
2019/07/26 Python
基于Python实现扑克牌面试题
2019/12/11 Python
Python IDE环境之 新版Pycharm安装详细教程
2020/03/05 Python
在python中使用nohup命令说明
2020/04/16 Python
班班通校本培训方案
2014/03/12 职场文书
优秀应届毕业生自荐书
2014/06/29 职场文书
四风自我剖析材料
2014/09/30 职场文书
乡镇干部个人对照检查材料思想汇报
2014/10/04 职场文书
2015年检验科工作总结
2015/04/27 职场文书
幼儿园庆六一主持词
2015/06/30 职场文书
严以律己学习心得体会
2016/01/13 职场文书
学者《孟子》名人名言
2019/08/09 职场文书
Web前端:CSS最强总结 附详细代码
2021/03/31 HTML / CSS