Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1125644
  • 博文数量: 170
  • 博客积分: 1603
  • 博客等级: 上尉
  • 技术积分: 1897
  • 用 户 组: 普通用户
  • 注册时间: 2010-07-09 15:54
文章分类

全部博文(170)

文章存档

2016年(27)

2015年(21)

2014年(27)

2013年(21)

2012年(7)

2011年(67)

我的朋友

分类: Python/Ruby

2013-06-06 15:10:36

原来就见过@property,但是一直不知道这个是干嘛的
今天看pyHook的的使用代码的时候正好解决了这个问题
问题源自下面代码的第52行


点击(此处)折叠或打开

  1. # -*- coding: utf-8 -*-
  2. #
  3. # by oldj
  4. # <a href="" rel="nofollow">http://oldj.net/</a>
  5. #
  6.  
  7. import pythoncom
  8. import pyHook
  9.  
  10. def onMouseEvent(event):
  11.     # 监听鼠标事件
  12.     print "MessageName:", event.MessageName
  13.     print "Message:", event.Message
  14.     print "Time:", event.Time
  15.     print "Window:", event.Window
  16.     print "WindowName:", event.WindowName
  17.     print "Position:", event.Position
  18.     print "Wheel:", event.Wheel
  19.     print "Injected:", event.Injected
  20.     print "---"
  21.  
  22.     # 返回 True 以便将事件传给其它处理程序
  23.     # 注意,这儿如果返回 False ,则鼠标事件将被全部拦截
  24.     # 也就是说你的鼠标看起来会僵在那儿,似乎失去响应了
  25.     return True
  26.  
  27. def onKeyboardEvent(event):
  28.     # 监听键盘事件
  29.     print "MessageName:", event.MessageName
  30.     print "Message:", event.Message
  31.     print "Time:", event.Time
  32.     print "Window:", event.Window
  33.     print "WindowName:", event.WindowName
  34.     print "Ascii:", event.Ascii, chr(event.Ascii)
  35.     print "Key:", event.Key
  36.     print "KeyID:", event.KeyID
  37.     print "ScanCode:", event.ScanCode
  38.     print "Extended:", event.Extended
  39.     print "Injected:", event.Injected
  40.     print "Alt", event.Alt
  41.     print "Transition", event.Transition
  42.     print "---"
  43.  
  44.     # 同鼠标事件监听函数的返回值
  45.     return True
  46.  
  47. def main():
  48.     # 创建一个“钩子”管理对象
  49.     hm = pyHook.HookManager()
  50.  
  51.     # 监听所有键盘事件
  52.     hm.KeyDown = onKeyboardEvent
  53.     # 设置键盘“钩子”
  54.     hm.HookKeyboard()
  55.  
  56.     # 监听所有鼠标事件
  57.     hm.MouseAll = onMouseEvent
  58.     # 设置鼠标“钩子”
  59.     hm.HookMouse()
  60.  
  61.     # 进入循环,如不手动关闭,程序将一直处于监听状态
  62.     pythoncom.PumpMessages()
  63.  
  64. if __name__ == "__main__":
  65.     main()
hm.MouseAll = onMouseEvent
这里我看得很奇怪,类里面的方法可以这样直接赋值(绑定)过去?
直接可以这样的话,平时就不用继承了吧....所以搜索了下正好有个相关的网页说了
https://blog.lzhaohao.info/archive/python-dynamic-instance-bound-method-access-to-private-method/
“要动态为实例绑定方法,可以使用new模块”——这个new好像更加复杂,所以我们先不关注这个new,只关注这个结论.....
这里没有用new,所以直接把这里理解为绑定方法是不对的

所以还是要看pyHook的源代码
找到KeyDown,发现
KeyDown = property(fset=SubscribeKeyDown)

这个property是干啥的?
详细说明
http://www.ibm.com/developerworks/cn/opensource/os-pythondescriptors/
这个自己去看

简单说明
http://www.cnblogs.com/lovemo1314/archive/2011/05/03/2035600.html
--------------------------------------------------------------------------------转载的分割线---------------------------------------------------------------------------------------------------------------------------
 1.现在介绍第一种使用property属性的方法:

在该类中定义三个函数,分别用作赋值、取值和删除变量(此处表达也许不很清晰,请看示例)

点击(此处)折叠或打开

  1. def getx(self):
  2.     return self.__x
  3. def setx(self,value):
  4.   self.__x=value
  5. def delx(self):
  6.   del self.__x
  7. x=property(getx,setx,delx,'')
property函数原型为property(fget=None,fset=None,fdel=None,doc=None),所以根据自己需要定义相应的函数即可。
现在这个类中的x属性便已经定义好了,我们可以先定义一个C的实例c=C(),然后赋值c.x=100,取值y=c.x,删除:del c.x。是不是很简单呢?请看第二种方法(就是@property,作用一样写法简洁了点我就不贴过来了
--------------------------------------------------------------------------------转载的分割线---------------------------------------------------------------------------------------------------------------------------

回头看pyHook里的SubscribeKeyDown

点击(此处)折叠或打开

  1. def SubscribeKeyDown(self, func):
  2.     '''
  3.     Registers the given function as the callback for this keyboard event type.
  4.     Use the KeyDown property as a shortcut.

  5.     @param func: Callback function
  6.     @type func: callable
  7.     '''
  8.     if func is None:
  9.       self.disconnect(self.keyboard_funcs, HookConstants.WM_KEYDOWN)
  10.       self.disconnect(self.keyboard_funcs, HookConstants.WM_SYSKEYDOWN)
  11.     else:
  12.       self.connect(self.keyboard_funcs, HookConstants.WM_KEYDOWN, func)
  13.       self.connect(self.keyboard_funcs, HookConstants.WM_SYSKEYDOWN, func)
通过上述property的用法我们可以知道,由于定义了KeyDown = property(fset=SubscribeKeyDown),所以外部调用hm.KeyDown = onKeyboardEvent
相当于hm.SubscribeKeyDown(onKeyboardEvent)
作用有点类似于__setitem__和__getitem__


我们顺便看看pyHook的其他地方源代码,发现

点击(此处)折叠或打开

  1. switch(idHook) {
  2.       case WH_MOUSE_LL:
  3.         if(callback_funcs[idHook] != NULL)
  4.           break;

  5.         callback_funcs[idHook] = pyfunc;
  6.         Py_INCREF(callback_funcs[idHook]);

  7.         Py_BEGIN_ALLOW_THREADS
  8.         hHooks[idHook] = SetWindowsHookEx(WH_MOUSE_LL, cLLMouseCallback, (HINSTANCE) hMod, 0);
  9.         Py_END_ALLOW_THREADS
  10.         break;

  11.       case WH_KEYBOARD_LL:
  12.         if(callback_funcs[idHook] != NULL)
  13.           break;

  14.         callback_funcs[idHook] = pyfunc;
  15.         Py_INCREF(callback_funcs[idHook]);

  16.         Py_BEGIN_ALLOW_THREADS
  17.         hHooks[idHook] = SetWindowsHookEx(WH_KEYBOARD_LL, cLLKeyboardCallback, (HINSTANCE) hMod, 0);
  18.         Py_END_ALLOW_THREADS
  19.         break;

  20.       default:
  21.        return 0;
  22.     }
也就是说只能用WH_MOUSE_LL和WH_KEYBOARD_LL两个钩子(pyHook底层的c api也只调用这两钩子,所以继承类添加其他钩子是没用的),这两个钩子很搓的,所以结论 pyHook基本没用,老老实实去学ctypes。
阅读(2535) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~