Python Hook钩子原理与实战解析

Noah
Noah
发布时间:2026-10-13| 4人浏览过
原创

本文深入解析Python中Hook钩子的核心原理,阐述其作为编程机制与语言无关的特性。通过对比Windows消息响应机制,说明钩子函数、注册函数与回调函数的概念一致性。文章结合Python代码示例,演示如何定义挂载点、注册自定义逻辑以及执行流程,帮助开发者理解如何利用Hook机制实现灵活的功能扩展。

什么是钩子

此前曾转载过一篇关于回调函数的文章

钩子函数、注册函数与回调函数,这三者的概念本质上是相同的。所谓钩子函数,顾名思义,就是指将自己实现的hook函数在特定的时刻挂接到目标挂载点上。

具体包含三个要素: 1. hook函数:即由用户自行实现的函数,其类型需与挂载点匹配(包括返回值和参数列表)。 2. 挂接:也称为hook或注册(register),目的是使hook函数对目标可用。 3. 目标挂载点:即挂接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 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。