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 相关文章推荐
wxPython 入门教程
Oct 07 Python
对Python新手编程过程中如何规避一些常见问题的建议
Apr 01 Python
Python中pygame的mouse鼠标事件用法实例
Nov 11 Python
python语言使用技巧分享
May 31 Python
python中的随机函数random的用法示例
Jan 27 Python
浅谈pycharm的xmx和xms设置方法
Dec 03 Python
Python数据报表之Excel操作模块用法分析
Mar 11 Python
Python中字符串与编码示例代码
May 20 Python
Python中*args和**kwargs的区别详解
Sep 17 Python
Django权限设置及验证方式
May 13 Python
Python绘图之二维图与三维图详解
Aug 04 Python
Python使用xpath实现图片爬取
Sep 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 信息采集程序代码
2009/03/17 PHP
解析阿里云ubuntu12.04环境下配置Apache+PHP+PHPmyadmin+MYsql
2013/06/26 PHP
PHP生成随机密码方法汇总
2015/08/27 PHP
PHP内核学习教程之php opcode内核实现
2016/01/27 PHP
PHP利用超级全局变量$_POST来接收表单数据的实例
2016/11/05 PHP
详解PHP函数 strip_tags 处理字符串缺陷bug
2017/06/11 PHP
Laravel关联模型中过滤结果为空的结果集(has和with区别)
2018/10/18 PHP
jquery.ui.draggable中文文档(原文翻译)
2013/11/15 Javascript
JS使用getComputedStyle()方法获取CSS属性值
2014/04/23 Javascript
javascript进行四舍五入方法汇总
2014/12/16 Javascript
js仿土豆网带缩略图的焦点图片切换效果实现方法
2015/02/23 Javascript
javascript实现根据3原色制作颜色选择器的方法
2015/07/17 Javascript
jQuery使用$.ajax进行即时验证的方法
2015/12/08 Javascript
通过JS获取Request.QueryString()参数的值实现方法
2016/09/27 Javascript
JS实现的五级联动菜单效果完整实例
2017/02/23 Javascript
老生常谈jquery中detach()和remove()的区别
2017/03/02 Javascript
xmlplus组件设计系列之按钮(2)
2017/04/26 Javascript
详解webpack3如何正确引用并使用jQuery库
2017/08/26 jQuery
微信小程序实现文字跑马灯效果
2020/05/26 Javascript
JavaScript封装的常用工具类库bee.js用法详解【经典类库】
2018/09/03 Javascript
JS实现获取数组中最大值或最小值功能示例
2019/03/02 Javascript
js对象属性名驼峰式转下划线的实例代码
2020/09/17 Javascript
Python求解任意闭区间的所有素数
2018/06/10 Python
python中ASCII码和字符的转换方法
2018/07/09 Python
Python 实现王者荣耀中的敏感词过滤示例
2019/01/21 Python
python 通过类中一个方法获取另一个方法变量的实例
2019/01/22 Python
Flask使用Pyecharts在单个页面展示多个图表的方法
2019/08/05 Python
Python3.7+tkinter实现查询界面功能
2019/12/24 Python
Nike加拿大官网:Nike.com (CA)
2019/04/09 全球购物
2013年入党人员的自我鉴定
2013/10/25 职场文书
高中军训广播稿
2014/01/14 职场文书
信息技术教学反思
2014/02/12 职场文书
个人师德师风自我剖析材料
2014/09/29 职场文书
党员干部反四风民主生活会对照检查材料思想汇报
2014/10/12 职场文书
Python使用openpyxl批量处理数据
2021/06/23 Python
Python可变集合和不可变集合的构造方法大全
2021/12/06 Python