源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

详解Python开发中如何使用Hook技巧

  • 时间:2022-04-23 19:03 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:详解Python开发中如何使用Hook技巧
什么是Hook,就是在一个已有的方法上加入一些钩子,使得在该方法执行前或执行后另在做一些额外的处理,那么Hook技巧有什么作用以及我们为什么需要使用它呢,事实上如果一个项目在设计架构时考虑的足够充分,模块抽象的足够合理,设计之初为以后的扩展预留了足够的接口,那么我们完全可以不需要Hook技巧。但恰恰架构人员在项目设计之初往往没办法想的足够的深远,使得后续在扩展时深圳面临重构的痛苦,这时Hook技巧似乎可以为我们带来一记缓兵之计,通过对旧的架构进行加钩子来满足新的扩展需求。 下面我们就来看看如果进行Hook处理,我们按照Hook的对象的层级来逐一介绍 [b]对类进行Hook[/b] 也就是说我们得钩子需要监控到类的创建等操作,然后在此之前或之后做我们希望的操作 [b]1、Hook类的创建[/b] 你可以在写一个类的时候为其添加__metaclass__属性
class Foo(Bar): __metaclass__ = something…
Python创建类的过程是这样的: Foo中有__metaclass__这个属性吗?如果是,Python会在内存中通过__metaclass__创建一个名字为Foo的类。如果Python没有找到__metaclass__,它会继续在Bar(父类)中寻找__metaclass__属性,并尝试做和前面同样的操作。如果Python在任何父类中都找不到__metaclass__,它就会在模块层次中去寻找__metaclass__,并尝试做同样的操作。如果还是找不到__metaclass__,Python就会用内置的type来创建这个类对象。 所以我们需要在给__metaclass__属性的值是一个能够创建一个类的东西,即一个继承type的类。 比如:
_singleton@singletonclass MyClass(object): a = 1 def __init__(self, x=0): self.x = x
我们使用singleton方法把MyClass修饰为了一个单例模式,同时我们也在singleton方法中实现了对MyClass实例过程的监控。 对方法进行Hook 1、修饰符来Hook方法 1)修饰不带参数的方法
wrap@somethingdef func(): pass
2)修饰带参数的方法
wrap@somethingdef func(a,b): pass
3)使用带参数的修饰符来修饰方法
new_func@something(1,2)def func(a,b): pass
[b]其他Hook[/b] 1、Hook内建方法
wrapped@my_decdef foo(): pass
这样处理后,foo方法的签名与被修饰之前保持了一致,否则签名将会变成my_dec方法的签名 [b]2、使用decorator模块来做修饰器[/b]
decorator@decoratordef wrap(f,*args,**kw): print start f(*args,**kw) print end#这样wrap方法就变成了一个decorator@wrapdef func(): print func
[b]3、使用类做修饰器[/b]
end@testdef func(): print funcfunc()startfuncend
实际应用中很少遇到可以使用一个类作为修饰器,但实际上只要一个类实现了__call__方法,其就可以作为一个修饰器存在了,并且由于类的可操作性较方法更强大,所以类做修饰器也可以实现更丰富的特性。 下面留个示例深入理解
# -*- coding: utf-8 -*- # 
import pythoncom 
import pyHook 
def onMouseEvent(event): 
  # 监听鼠标事件  
  print "MessageName:",event.MessageName 
  print "Message:", event.Message  
  print "Time:", event.Time  
  print "Window:", event.Window  
  print "WindowName:", event.WindowName  
  print "Position:", event.Position  
  print "Wheel:", event.Wheel  
  print "Injected:", event.Injected   
  print "---"

  # 返回 True 以便将事件传给其它处理程序  
  # 注意,这儿如果返回 False ,则鼠标事件将被全部拦截  
  # 也就是说你的鼠标看起来会僵在那儿,似乎失去响应了  
  return True

def onKeyboardEvent(event):
  # 监听键盘事件  
  print "MessageName:", event.MessageName  
  print "Message:", event.Message  
  print "Time:", event.Time  
  print "Window:", event.Window  
  print "WindowName:", event.WindowName  
  print "Ascii:", event.Ascii, chr(event.Ascii)  
  print "Key:", event.Key  
  print "KeyID:", event.KeyID  
  print "ScanCode:", event.ScanCode  
  print "Extended:", event.Extended  
  print "Injected:", event.Injected  
  print "Alt", event.Alt  
  print "Transition", event.Transition  
  print "---"  
  # 同鼠标事件监听函数的返回值  
  return True 

def main():  
  # 创建一个“钩子”管理对象  
  hm = pyHook.HookManager()  
  # 监听所有键盘事件  
  hm.KeyDown = onKeyboardEvent  
  # 设置键盘“钩子”  
  hm.HookKeyboard()  
  # 监听所有鼠标事件  
  hm.MouseAll = onMouseEvent  
  # 设置鼠标“钩子”  
  hm.HookMouse()  
  # 进入循环,如不手动关闭,程序将一直处于监听状态  
  pythoncom.PumpMessages() 

if __name__ == "__main__":  
  main()

#将test.py变为test.exe
#Get py2exe from http://www.py2exe.org/        

from distutils.core import setup
import py2exe

setup(console=['test.py'])

#cmd下执行:python setup.py py2exe,在dist目录下有exe和必备dll
#隐藏控制台,让其一闪而过
import ctypes 
whnd = ctypes.windll.kernel32.GetConsoleWindow() 
if whnd != 0: 
  ctypes.windll.user32.ShowWindow(whnd, 0) 
  ctypes.windll.kernel32.CloseHandle(whnd) 
[img]http://files.jb51.net/file_images/article/201711/2017111104007278.png?2017101104023[/img] 小编就先聊到这里,今天交流的内容都是硬知识,普通的开发过程中也许并不能使用的上,但了解这些知识对于编程能力的提高很有帮助,也能够帮助你更深入的理解Python的机制。也希望大家多多支持编程素材网。
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部