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中使用Beautiful Soup库的超详细教程
Apr 30 Python
Python实现控制台输入密码的方法
May 29 Python
Python 读写文件和file对象的方法(推荐)
Sep 12 Python
Python获取当前公网ip并自动断开宽带连接实例代码
Jan 12 Python
TensorFlow神经网络优化策略学习
Mar 09 Python
Python读写/追加excel文件Demo分享
May 03 Python
python 读取文件并把矩阵转成numpy的两种方法
Feb 12 Python
Django如何实现密码错误报错提醒
Sep 04 Python
五分钟学会怎么用Pygame做一个简单的贪吃蛇
Jan 06 Python
Pycharm 跳转回之前所在页面的操作
Feb 05 Python
python某漫画app逆向
Mar 31 Python
python opencv常用图形绘制方法(线段、矩形、圆形、椭圆、文本)
Apr 12 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
session在PHP大型web应用中的使用
2011/06/25 PHP
PHP 在数组中搜索给定的简单实例 array_search 函数
2016/06/13 PHP
JavaScript的类型简单说明
2010/09/03 Javascript
jQuery实现弹出窗口中切换登录与注册表单
2015/06/05 Javascript
纯javascript响应式树形菜单效果
2015/11/10 Javascript
JavaScript如何实现在文本框(密码框)输入提示语
2015/12/25 Javascript
jQuery事件用法详解
2016/10/06 Javascript
nodejs入门教程五:连接数据库的方法分析
2017/04/24 NodeJs
jQuery+ajax实现局部刷新的两种方法
2017/06/08 jQuery
JS实现中文汉字按拼音排序的方法
2017/10/09 Javascript
微信小程序登录按钮遮罩浮层效果的实现方法
2018/12/16 Javascript
详解Bootstrap 学习(一)入门
2019/04/12 Javascript
Node.js实现简单管理系统
2019/09/23 Javascript
JavaScript禁止右击保存图片,禁止拖拽图片的实现代码
2020/04/28 Javascript
python中List的sort方法指南
2014/09/01 Python
python写的一个squid访问日志分析的小程序
2014/09/17 Python
Python随机生成一个6位的验证码代码分享
2015/03/24 Python
老生常谈Python之装饰器、迭代器和生成器
2017/07/26 Python
Tensorflow之Saver的用法详解
2018/04/23 Python
python实现车牌识别的示例代码
2019/08/05 Python
Python3如何在Windows和Linux上打包
2020/02/25 Python
Python sublime安装及配置过程详解
2020/06/29 Python
Pycharm无法打开双击没反应的问题及解决方案
2020/08/17 Python
五分钟带你搞懂python 迭代器与生成器
2020/08/30 Python
Python中logging日志的四个等级和使用
2020/11/17 Python
python更新数据库中某个字段的数据(方法详解)
2020/11/18 Python
美国山地自行车、露营、户外装备和服装购物网站:Aventuron
2018/05/05 全球购物
教师研修随笔感言
2014/01/23 职场文书
记帐员岗位责任制
2014/02/08 职场文书
小学班主任评语大全
2014/04/23 职场文书
回门宴新娘答谢词
2015/09/29 职场文书
《这片土地是神圣的》教学反思
2016/02/16 职场文书
为什么阅读对所有年龄段的孩子都很重要?
2019/07/08 职场文书
python基于tkinter制作下班倒计时工具
2021/04/28 Python
HTML基础详解(上)
2021/10/16 HTML / CSS
html解决浏览器记住密码输入框的问题
2023/05/07 HTML / CSS