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之??碌某?? target=
Sep 12 Python
举例讲解Python中is和id的用法
Apr 03 Python
python爬虫入门教程--利用requests构建知乎API(三)
May 25 Python
Python简单定义与使用字典dict的方法示例
Jul 25 Python
Python实现发送与接收邮件的方法详解
Mar 28 Python
Python使用numpy产生正态分布随机数的向量或矩阵操作示例
Aug 22 Python
python+opencv像素的加减和加权操作的实现
Jul 14 Python
PyQt5+Caffe+Opencv搭建人脸识别登录界面
Aug 28 Python
Python 3.6 中使用pdfminer解析pdf文件的实现
Sep 25 Python
Python中__repr__和__str__区别详解
Nov 07 Python
keras分类之二分类实例(Cat and dog)
Jul 09 Python
python 如何用terminal输入参数
May 25 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实现session共享的实例方法
2019/09/19 PHP
Yii 框架使用数据库(databases)的方法示例
2020/05/19 PHP
有一段有意思的代码-javascript现实多行信息
2007/08/26 Javascript
ie和firefox不兼容的解决方法集合
2009/04/28 Javascript
从数据结构分析看:用for each...in 比 for...in 要快些
2013/04/17 Javascript
给超链接添加特效鼠标移动展示提示信息且随鼠标移动
2013/10/17 Javascript
js如何打印object对象
2015/10/16 Javascript
jquery.validate 自定义验证方法及validate相关参数
2016/01/18 Javascript
nodejs修复ipa处理过的png图片
2016/02/17 NodeJs
AngularJS 遇到的小坑与技巧小结
2016/06/07 Javascript
JavaScript表单验证开发
2016/11/23 Javascript
Vuejs中的watch实例详解(监听者)
2020/01/05 Javascript
vue实现几秒后跳转新页面代码
2020/09/09 Javascript
JavaScript实现随机点名小程序
2020/10/29 Javascript
解决vue watch数据的方法被调用了两次的问题
2020/11/07 Javascript
如何在现代JavaScript中编写异步任务
2021/01/31 Javascript
[52:02]完美世界DOTA2联赛PWL S2 FTD.C vs SZ 第一场 11.27
2020/11/30 DOTA
python通过线程实现定时器timer的方法
2015/03/16 Python
python读取json文件并将数据插入到mongodb的方法
2015/03/23 Python
Python制作钉钉加密/解密工具
2016/12/07 Python
微信跳一跳辅助python代码实现
2018/01/05 Python
快速了解Python中的装饰器
2018/01/11 Python
python学生信息管理系统
2018/03/13 Python
使用python生成杨辉三角形的示例代码
2018/08/29 Python
python添加菜单图文讲解
2019/06/04 Python
django 数据库连接模块解析及简单长连接改造方法
2019/08/29 Python
scrapy爬虫:scrapy.FormRequest中formdata参数详解
2020/04/30 Python
深入了解NumPy 高级索引
2020/07/24 Python
CSS3实现可关闭的下拉手风琴菜单效果
2015/08/31 HTML / CSS
夏尔巴人登珠峰品牌:Sherpa Adventure Gear
2018/02/08 全球购物
Giglio俄罗斯奢侈品购物网:男士、女士、儿童高级时装
2018/07/27 全球购物
美国最大的在线寄售和旧货店:Swap.com
2018/08/27 全球购物
澳大利亚领先的内衣店:Bendon Lingerie澳大利亚
2020/05/15 全球购物
JAVA语言如何进行异常处理,关键字:throws,throw,try,catch,finally分别代表什么意义?在try块中可以抛出异常吗?
2013/07/02 面试题
2014预备党员党课学习心得范文
2014/07/08 职场文书
大国崛起英国观后感
2015/06/02 职场文书