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 18 Python
Python中几个比较常见的名词解释
Jul 04 Python
Python中str.format()详解
Mar 12 Python
Python urls.py的三种配置写法实例详解
Apr 28 Python
python 表达式和语句及for、while循环练习实例
Jul 07 Python
Django安装配置mysql的方法步骤
Oct 15 Python
Django如何防止定时任务并发浅析
May 14 Python
Python中Unittest框架的具体使用
Aug 27 Python
python tornado修改log输出方式
Nov 18 Python
python encrypt 实现AES加密的实例详解
Feb 20 Python
Pytorch十九种损失函数的使用详解
Apr 29 Python
python 爬取吉首大学网站成绩单
Jun 02 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
sony ICF-2010 拆解与改装
2021/03/02 无线电
CI框架源码阅读,系统常量文件constants.php的配置
2013/02/28 PHP
phpmyadmin配置文件现在需要绝密的短密码(blowfish_secret)的2种解决方法
2014/05/07 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(十四)
2014/06/26 PHP
PHP中的traits实现代码复用使用实例
2015/05/13 PHP
PHP图像处理技术实例总结【绘图、水印、验证码、图像压缩】
2018/12/08 PHP
php多进程应用场景实例详解
2019/07/22 PHP
一个很简单的办法实现TD的加亮效果.
2006/06/29 Javascript
js实现动态添加、删除行、onkeyup表格求和示例
2013/08/18 Javascript
浅谈javascript 归并方法
2015/01/21 Javascript
node.js操作mongodb学习小结
2015/04/25 Javascript
在JavaScript中操作时间之getMonth()方法的使用
2015/06/10 Javascript
jQuery插件jquery-barcode实现条码打印的方法
2015/11/25 Javascript
IE8 内存泄露(内存一直增长 )的原因及解决办法
2016/04/06 Javascript
基于Vuejs实现购物车功能
2016/08/02 Javascript
jQuery实现点击查看大图并以弹框的形式居中
2016/08/08 Javascript
canvas实现图片根据滑块放大缩小效果
2017/02/24 Javascript
Angular实现预加载延迟模块的示例
2017/10/12 Javascript
React Native react-navigation 导航使用详解
2017/12/01 Javascript
使用Vue实现图片上传的三种方式
2018/07/17 Javascript
vue实现移动端返回顶部
2020/10/12 Javascript
深入理解javascript中的this
2021/02/08 Javascript
Python3实现的Mysql数据库操作封装类
2018/06/06 Python
OpenCV 模板匹配
2019/07/10 Python
python config文件的读写操作示例
2019/09/27 Python
Pytorch 神经网络—自定义数据集上实现教程
2020/01/07 Python
使用Python爬虫库requests发送表单数据和JSON数据
2020/01/25 Python
paramiko使用tail实时获取服务器的日志输出详解
2020/12/06 Python
你正在寻找的CSS3 动画技术
2011/07/27 HTML / CSS
使用phonegap创建联系人的实现方法
2017/03/30 HTML / CSS
Nike法国官方网站:Nike.com FR
2018/07/22 全球购物
2014年端午节演讲稿范文
2014/05/23 职场文书
导游词书写之黄山
2019/08/06 职场文书
CSS 文字装饰 text-decoration & text-emphasis 详解
2021/04/06 HTML / CSS
Python+Selenium实现抖音、快手、B站、小红书、微视、百度好看视频、西瓜视频、微信视频号、搜狐视频、一点号、大风号、趣头条等短视频自动发布
2022/04/13 Python
Linux中sftp常用命令整理
2022/06/28 Servers