Python钩子函数

python hook 机制

一、 概念

1、 hook概述

hook,又称钩子,在C/C++中一般叫做回调函数。钩子是从功能角度描述这种编程模式,回调则是从函数调用时间角度描述的。通常理解的hook是在一个已有的方法上加入一些钩子,使得在该方法执行前或执行后另在做一些额外的处理。如我们熟知的windows系统消息响应事件,鼠标点击对程序产生的影响是有程序自己决定的,但是程序的执行是受制于框架(windows系统),框架提供了一些通用的流程执行,但是往往框架或流程在设计时无法完全预料到以后的使用会有什么新需求,或者有些行为只有在运行时才能确定的。这就产生了回调的需求,即用户提供需求,框架负责执行,流程先于具体需求,当触发或者满足某种条件时,执行Hook函数。hook函数的数据也是由用户自己提供的,框架只负责流程执行,这样框架的通用性就能大大提高。

2、 hook

钩子函数:就是把我们自己实现的hook函数在某一时刻挂接到目标挂载点上。

  • hook函数:就是我们自己实现的函数,函数类型与挂载点匹配(返回值,参数列表)
  • 挂接:也就是hook或者叫注册(register),使得hook函数对目标可用
  • 目标挂载点:也就是挂我们hook函数的地方

二、 示例

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):
        """一天的生活"""
        self.get_up()
        time.sleep(2)
        # 如果注册了钩子函数
        if self.watch_tv_func is not None:
            self.watch_tv_func(self.name)
        else: # 没有注册钩子函数
            print("no tv to watch")

        time.sleep(2)
        # 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)
        else: # unhooked
            print("nothing to eat at dinner")

        time.sleep(2)
        self.go_to_sleep()

def watch_daydayup(name): # hook函数
    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)


def test():
    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()

test()
posted @ 2022-08-10 19:59  Kenny_LZK  阅读(450)  评论(0编辑  收藏  举报