python学习之hook钩子的原理和使用


Posted in Python onOctober 25, 2018

什么是钩子

之前有转一篇关于回调函数的文章

钩子函数、注册函数、回调函数,他们的概念其实是一样的。
钩子函数,顾名思义,就是把我们自己实现的hook函数在某一时刻挂接目标挂载点上。

1. hook函数,就是我们自己实现的函数,函数类型与挂载点匹配(返回值,参数列表)
2. 挂接,也就是hook或者叫注册(register),使得hook函数对目标可用
3. 目标挂载点,也就是挂我们hook函数的地方(我们想在这个目标点实现我们自己的功能)

先看一张图:

 python学习之hook钩子的原理和使用

hook的概念在windows的消息响应机制里面体现的尤为明显。可能我们大家有写过windows桌面相关的程序(像MFC),里面有各种消息监听响应机制。比如,要监听鼠标左键是否按下这个事件,我们要去实现一个onLeftKeyDown()之类的方法,该方法可以称为钩子函数。同时,我们还要去注册钩子函数,MFC中是通过一组宏来实现的。这样当鼠标左键按下后,就能调到我们定义的方法了。

为什么需要钩子

大家思考一下上面这个例子,左键按下方法具体的逻辑是由框架自身去实现,还是由我们用户(调用者)去实现呢?显然应该由我们自己去实现。要提供通用的框架能力,框架自身去实现该方法功能,是没有意义的,所以框架给提供一个挂载的point,把具体逻辑的实现交给用户就好了,灵活可用。

钩子使用

hook是一个编程机制,与语言无关。这里给个python的简单例子,帮助大家理解:

import time

class LazyPerson(object):
  def __init__(self, name):
    self.name = name
    self.watch_tv_func = None
    self.have_dinner_func = None

  def get_up(self):
    print("%s get up at:%s" % (self.name, time.time()))

  def go_to_sleep(self):
    print("%s go to sleep at:%s" % (self.name, time.time()))

  def register_tv_hook(self, watch_tv_func):
    self.watch_tv_func = watch_tv_func

  def register_dinner_hook(self, have_dinner_func):
    self.have_dinner_func = have_dinner_func

  def enjoy_a_lazy_day(self):

    # get up
    self.get_up()
    time.sleep(3)
    # watch tv
    # check the watch_tv_func(hooked or unhooked)
    # hooked
    if self.watch_tv_func is not None:
      self.watch_tv_func(self.name)
    # unhooked
    else:
      print("no tv to watch")
    time.sleep(3)
    # have dinner
    # check the have_dinner_func(hooked or unhooked)
    # hooked
    if self.have_dinner_func is not None:
      self.have_dinner_func(self.name)
    # unhooked
    else:
      print("nothing to eat at dinner")
    time.sleep(3)
    self.go_to_sleep()

def watch_daydayup(name):
  print("%s : The program ---day day up--- is funny!!!" % name)

def watch_happyfamily(name):
  print("%s : The program ---happy family--- is boring!!!" % name)

def eat_meat(name):
  print("%s : The meat is nice!!!" % name)


def eat_hamburger(name):
  print("%s : The hamburger is not so bad!!!" % name)


if __name__ == "__main__":
  lazy_tom = LazyPerson("Tom")
  lazy_jerry = LazyPerson("Jerry")
  # register hook
  lazy_tom.register_tv_hook(watch_daydayup)
  lazy_tom.register_dinner_hook(eat_meat)
  lazy_jerry.register_tv_hook(watch_happyfamily)
  lazy_jerry.register_dinner_hook(eat_hamburger)
  # enjoy a day
  lazy_tom.enjoy_a_lazy_day()
  lazy_jerry.enjoy_a_lazy_day()

代码运行结果:

Tom get up at:1509246940.32
Tom : The program ---day day up--- is funny!!!
Tom : The meat is nice!!!
Tom go to sleep at:1509246949.34
Jerry get up at:1509246949.34
Jerry : The program ---happy family--- is boring!!!
Jerry : The hamburger is not so bad!!!
Jerry go to sleep at:1509246958.37

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python实现中文输出的两种方法
May 09 Python
Python函数可变参数定义及其参数传递方式实例详解
May 25 Python
使用Python编写基于DHT协议的BT资源爬虫
Mar 19 Python
python日志记录模块实例及改进
Feb 12 Python
python中模块查找的原理与方法详解
Aug 11 Python
python画出三角形外接圆和内切圆的方法
Jan 25 Python
python消费kafka数据批量插入到es的方法
Dec 27 Python
Python实现去除图片中指定颜色的像素功能示例
Apr 13 Python
django drf框架中的user验证以及JWT拓展的介绍
Aug 12 Python
Python 列表的清空方式
Jan 13 Python
踩坑:pytorch中eval模式下结果远差于train模式介绍
Jun 23 Python
基于PyTorch实现一个简单的CNN图像分类器
May 29 Python
基于Python实现定时自动给微信好友发送天气预报
Oct 25 #Python
python批量修改图片后缀的方法(png到jpg)
Oct 25 #Python
python bmp转换为jpg 并删除原图的方法
Oct 25 #Python
virtualenv 指定 python 解释器的版本方法
Oct 25 #Python
解决python3读取Python2存储的pickle文件问题
Oct 25 #Python
python 解压pkl文件的方法
Oct 25 #Python
纯用NumPy实现神经网络的示例代码
Oct 24 #Python
You might like
PHP中10个不常见却非常有用的函数
2010/03/21 PHP
解决ThinkPHP下使用上传插件Uploadify浏览器firefox报302错误的方法
2015/12/18 PHP
Yii框架用户登录session丢失问题解决方法
2017/01/07 PHP
PHP rsa加密解密算法原理解析
2020/12/09 PHP
JavaScript 入门基础知识 想学习js的朋友可以参考下
2009/12/26 Javascript
理解javascript正则表达式
2016/03/08 Javascript
Javascript实现代码折叠功能
2016/08/25 Javascript
让编辑器支持word复制黏贴、截屏的js代码
2016/10/17 Javascript
详解require.js配置路径的用法和css的引入
2017/09/06 Javascript
JS中promise化微信小程序api
2018/04/12 Javascript
js实现按钮开关单机下拉菜单效果
2018/11/22 Javascript
微信小程序获取复选框全选反选选中的值(实例代码)
2019/12/17 Javascript
Vue select 绑定动态变量的实例讲解
2020/10/22 Javascript
[57:59]完美世界DOTA2联赛循环赛 Ink Ice vs LBZS BO2第一场 11.05
2020/11/05 DOTA
总结Python编程中函数的使用要点
2016/03/20 Python
Python彩色化Linux的命令行终端界面的代码实例分享
2016/07/02 Python
Python操作MongoDB数据库的方法示例
2018/01/04 Python
python docx 中文字体设置的操作方法
2018/05/08 Python
Python3实现的Mysql数据库操作封装类
2018/06/06 Python
Python对Tornado请求与响应的数据处理
2020/02/12 Python
python和php哪个容易学
2020/06/19 Python
python中setuptools的作用是什么
2020/06/19 Python
浅析python连接数据库的重要事项
2021/02/22 Python
用gpu训练好的神经网络,用tensorflow-cpu跑出错的原因及解决方案
2021/03/03 Python
日本一家专门经营各种箱包的大型网站:Traveler Store
2016/08/03 全球购物
法律专业应届本科毕业生求职信
2013/10/25 职场文书
仓库主管的岗位职责
2013/12/04 职场文书
汽车专业大学生职业生涯规划范文
2014/01/07 职场文书
亲戚结婚的请假条
2014/02/11 职场文书
保护动物倡议书
2014/04/15 职场文书
电力安全事故反思
2014/04/27 职场文书
学校学雷锋活动总结
2014/06/26 职场文书
2015年重阳节活动总结
2015/03/24 职场文书
2015年医院药剂科工作总结
2015/05/04 职场文书
股东合作协议书模板2篇
2019/11/05 职场文书
html+css实现环绕倒影加载特效
2021/07/07 HTML / CSS