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 相关文章推荐
35个Python编程小技巧
Apr 01 Python
Python模拟登陆实现代码
Jun 14 Python
分享几道你可能遇到的python面试题
Jul 24 Python
python使用tensorflow深度学习识别验证码
Apr 03 Python
对python的unittest架构公共参数token提取方法详解
Dec 17 Python
详解Appium+Python之生成html测试报告
Jan 04 Python
Django实现学生管理系统
Feb 26 Python
python实现LBP方法提取图像纹理特征实现分类的步骤
Jul 11 Python
Python处理session的方法整理
Aug 29 Python
python实现堆排序的实例讲解
Feb 21 Python
Lombok插件安装(IDEA)及配置jar包使用详解
Nov 04 Python
python基础之while循环语句的使用
Apr 20 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中get_cfg_var()和ini_get()的用法及区别
2015/03/04 PHP
php实现将Session写入数据库
2015/07/26 PHP
PHP创建单例后台进程的方法示例
2017/05/23 PHP
ASP中进行HTML数据及JS数据编码函数
2009/11/11 Javascript
深入理解JavaScript系列(9) 根本没有“JSON对象”这回事!
2012/01/15 Javascript
NodeJs中的非阻塞方法介绍
2012/06/05 NodeJs
js实现翻页后保持checkbox选中状态的实现方法
2012/11/03 Javascript
node.js中的path.basename方法使用说明
2014/12/09 Javascript
JS实现漂亮的时间选择框效果
2016/08/20 Javascript
Vue数据驱动模拟实现2
2017/01/11 Javascript
Javascript中字符串和数字的操作方法整理
2017/01/22 Javascript
使用JavaScript进行表单校验功能
2017/08/01 Javascript
JS设计模式之命令模式概念与用法分析
2018/02/06 Javascript
轻量级富文本编辑器wangEditor结合vue使用方法示例
2018/10/10 Javascript
JavaScript实现汉字转换为拼音及缩写的方法示例
2019/03/28 Javascript
vue操作动画的记录animate.css实例代码
2019/04/26 Javascript
Js数组扁平化实现方法代码总汇
2020/11/11 Javascript
vue切换菜单取消未完成接口请求的案例
2020/11/13 Javascript
编写v-for循环的技巧汇总
2020/12/01 Javascript
Python中的默认参数实例分析
2018/01/29 Python
Python基于pycrypto实现的AES加密和解密算法示例
2018/04/10 Python
python3+PyQt5实现文档打印功能
2018/04/24 Python
Python3多线程操作简单示例
2018/05/22 Python
使用Python对微信好友进行数据分析
2018/06/27 Python
Python读取数据集并消除数据中的空行方法
2018/07/12 Python
纯用NumPy实现神经网络的示例代码
2018/10/24 Python
对Python3中dict.keys()转换成list类型的方法详解
2019/02/03 Python
在Python中使用MySQL--PyMySQL的基本使用方法
2019/11/19 Python
Python如何访问字符串中的值
2020/02/09 Python
Python虚拟环境virtualenv创建及使用过程图解
2020/12/08 Python
SportsDirect.com新加坡:英国第一体育零售商
2019/03/30 全球购物
Currentbody西班牙:美容仪专家
2019/09/28 全球购物
简历自荐信
2013/12/02 职场文书
新学期家长寄语
2014/01/19 职场文书
导游词之吉林花园山
2019/10/17 职场文书
巧用 -webkit-box-reflect 倒影实现各类动效(小结)
2021/04/22 HTML / CSS