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程序员开发中常犯的10个错误
Jul 07 Python
python使用正则表达式替换匹配成功的组并输出替换的次数
Nov 22 Python
Python zip()函数用法实例分析
Mar 17 Python
Python读写/追加excel文件Demo分享
May 03 Python
Python解析并读取PDF文件内容的方法
May 08 Python
Python简单定义与使用二叉树示例
May 11 Python
快速解决pandas.read_csv()乱码的问题
Jun 15 Python
在Pandas中DataFrame数据合并,连接(concat,merge,join)的实例
Jan 29 Python
Laravel框架表单验证格式化输出的方法
Sep 25 Python
Python chardet库识别编码原理解析
Feb 18 Python
Python 的 __str__ 和 __repr__ 方法对比
Sep 02 Python
用Python编写简单的gRPC服务的详细过程
Jul 04 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 current函数获取未知字符键名数组第一个元素的值
2013/06/24 PHP
改写ThinkPHP的U方法使其路由下分页正常
2014/07/02 PHP
Laravel框架数据库CURD操作、连贯操作总结
2014/09/03 PHP
Javascript开发包大全整理
2006/12/22 Javascript
JQuery判断子iframe何时加载完成解决方案
2013/08/20 Javascript
在javascript中执行任意html代码的方法示例解读
2013/12/25 Javascript
Javascript中封装window.open解决不兼容问题
2014/09/28 Javascript
kindeditor修复会替换script内容的问题
2015/04/03 Javascript
js显示文本框提示文字的方法
2015/05/07 Javascript
javascript实现网页屏蔽Backspace事件,输入框不屏蔽
2015/07/21 Javascript
基于javascript制作微博发布栏效果
2016/04/04 Javascript
微信小程序 删除项目工程实现步骤
2016/11/10 Javascript
微信小程序 数组(增,删,改,查)等操作实例详解
2017/01/05 Javascript
微信小程序时间轴实现方法示例
2019/01/14 Javascript
详解如何实现Element树形控件Tree在懒加载模式下的动态更新
2019/04/25 Javascript
jQuery实现带进度条的轮播图
2020/09/13 jQuery
Python实现Windows上气泡提醒效果的方法
2015/06/03 Python
基于Python数据可视化利器Matplotlib,绘图入门篇,Pyplot详解
2017/10/13 Python
python实现随机森林random forest的原理及方法
2017/12/21 Python
python http接口自动化脚本详解
2018/01/02 Python
python的命名规则知识点总结
2019/10/04 Python
python元组的概念知识点
2019/11/19 Python
如何使用python的ctypes调用医保中心的dll动态库下载医保中心的账单
2020/05/24 Python
python中有帮助函数吗
2020/06/19 Python
美国在线宠物商店:Chewy
2019/01/12 全球购物
现金会计岗位职责
2013/12/05 职场文书
业务主管岗位职责范本
2013/12/25 职场文书
药学专业学生的自我评价分享
2014/02/06 职场文书
论文指导教师评语
2014/04/28 职场文书
群众路线对照检查剖析材料
2014/10/09 职场文书
英文商务邀请函范文
2015/01/31 职场文书
英文慰问信范文
2015/03/24 职场文书
盗窃案辩护词
2015/05/21 职场文书
聊聊golang中多个defer的执行顺序
2021/05/08 Golang
Java 垃圾回收超详细讲解记忆集和卡表
2022/04/08 Java/Android
使用 DataAnt 监控 Apache APISIX的原理解析
2022/07/07 Servers