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 图片验证码代码
Dec 07 Python
用Python脚本生成Android SALT扰码的方法
Sep 18 Python
Python实现SMTP发送邮件详细教程
Mar 02 Python
Python OpenCV 直方图的计算与显示的方法示例
Feb 08 Python
python中的json总结
Oct 11 Python
Python Pandas 如何shuffle(打乱)数据
Jul 30 Python
用python解压分析jar包实例
Jan 16 Python
Python3 中sorted() 函数的用法
Mar 24 Python
Jupyter Notebook 文件默认目录的查看以及更改步骤
Apr 14 Python
python中复数的共轭复数知识点总结
Dec 06 Python
Python截图并保存的具体实例
Jan 14 Python
Python之Sklearn使用入门教程
Feb 19 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
饭制《星际争霸》Mod:优化游戏机制 增加新单位
2017/07/02 星际争霸
SMARTY学习手记
2007/01/04 PHP
PHP ajax 分页类代码
2008/11/13 PHP
php 图片加水印与上传图片加水印php类
2010/05/12 PHP
简单的PHP多图上传小程序代码
2011/07/17 PHP
ThinkPHP的L方法使用简介
2014/06/18 PHP
PHP批量获取网页中所有固定种子链接的方法
2016/11/18 PHP
jQuery使用手册之一
2007/03/24 Javascript
jquery win 7透明弹出层效果的简单代码
2013/08/06 Javascript
jquery检测input checked 控件是否被选中的方法
2014/03/26 Javascript
gridview生成时如何去掉style属性中的border-collapse
2014/09/30 Javascript
js实现轮播图的完整代码
2020/10/26 Javascript
arctext.js实现文字平滑弯曲弧形效果的插件
2019/05/13 Javascript
通过Nodejs搭建网站简单实现注册登录流程
2019/06/14 NodeJs
python实现批量转换文件编码(批转换编码示例)
2014/01/23 Python
在Python编程过程中用单元测试法调试代码的介绍
2015/04/02 Python
Python+matplotlib实现计算两个信号的交叉谱密度实例
2018/01/08 Python
python之pandas用法大全
2018/03/13 Python
python爬虫获取百度首页内容教学
2018/12/23 Python
PythonWeb项目Django部署在Ubuntu18.04腾讯云主机上
2019/04/01 Python
TENSORFLOW变量作用域(VARIABLE SCOPE)
2020/01/10 Python
Python内建序列通用操作6种实现方法
2020/03/26 Python
pandas分组聚合详解
2020/04/10 Python
windows上彻底删除jupyter notebook的实现
2020/04/13 Python
Django缓存Cache使用详解
2020/11/30 Python
浅谈Html5多线程开发之WebWorkers
2018/05/02 HTML / CSS
Alba Moda瑞士网上商店:独家意大利时尚女装销售
2016/11/28 全球购物
法国美发器材和产品购物网站:Beauty Coiffure
2016/12/05 全球购物
What is the purpose of Void class? Void类的作用是什么?
2016/10/31 面试题
上海雨人软件技术开发有限公司测试题
2015/07/14 面试题
五年级科学教学反思
2014/02/05 职场文书
七夕情人节促销方案
2014/06/07 职场文书
小学语文国培研修日志
2015/11/13 职场文书
公务员岗前培训心得体会
2016/01/08 职场文书
《思路决定出路》读后感3篇
2019/12/11 职场文书
python神经网络学习 使用Keras进行回归运算
2022/05/04 Python