例子:
成都創(chuàng)新互聯(lián)公司致力于互聯(lián)網(wǎng)網(wǎng)站建設(shè)與網(wǎng)站營銷,提供網(wǎng)站建設(shè)、做網(wǎng)站、網(wǎng)站開發(fā)、seo優(yōu)化、網(wǎng)站排名、互聯(lián)網(wǎng)營銷、微信小程序開發(fā)、公眾號商城、等建站開發(fā),成都創(chuàng)新互聯(lián)公司網(wǎng)站建設(shè)策劃專家,為不同類型的客戶提供良好的互聯(lián)網(wǎng)應用定制解決方案,幫助客戶在新的全球化互聯(lián)網(wǎng)環(huán)境中保持優(yōu)勢。
#!/usr/bin/python
# Filename: class_init.py
class Person:
def __init__(self, name):
self.name = name
def sayHi(self):
print Hello, my name is, self.name
p = Person(Swaroop)
p.sayHi()
這個例子中就是在init方法中定義了參數(shù)name,然后調(diào)用的時候直接用類名person帶上傳參swaroop就行了,swaroop參數(shù)就會傳遞給sayhi(),整個流程就對應c中的構(gòu)造函數(shù)。
然后說鉤子,其實就是實現(xiàn)一種內(nèi)操作,有子進程的意思但又不是,至于裝飾函數(shù)是不是鉤子好像沒官方說法,我認為可以算是。裝飾器就是把一個函數(shù)對象返回給另一個函數(shù)來實現(xiàn)既定的功能,其實就是一種內(nèi)操作。
PS:很多東西都是相關(guān)的,比如方法和它的具體實現(xiàn)功能,等你用到它的功能以后就很好理解了,單純的研究理論也沒什么意思。尤其是這種比較抽象的概念。
WINDOWS的鉤子函數(shù)可以認為是WINDOWS的主要特性之一。利用它們,您可以捕捉您自己進程或其它進程發(fā)生的事件。通過“鉤掛”,您可以給WINDOWS一個處理或過濾事件的回調(diào)函數(shù),該函數(shù)也叫做“鉤子函數(shù)”,當每次發(fā)生您感興趣的事件時,WINDOWS都將調(diào)用該函數(shù)。一共有兩種類型的鉤子:局部的和遠程的。
局部鉤子僅鉤掛您自己進程的事件。
遠程的鉤子還可以將鉤掛其它進程發(fā)生的事件。遠程的鉤子又有兩種:
基于線程的 它將捕獲其它進程中某一特定線程的事件。簡言之,就是可以用來觀察其它進程中的某一特定線程將發(fā)生的事件。
系統(tǒng)范圍的 將捕捉系統(tǒng)中所有進程將發(fā)生的事件消息。 當您創(chuàng)建一個鉤子時,WINDOWS會先在內(nèi)存中創(chuàng)建一個數(shù)據(jù)結(jié)構(gòu),該數(shù)據(jù)結(jié)構(gòu)包含了鉤子的相關(guān)信息,然后把該結(jié)構(gòu)體加到已經(jīng)存在的鉤子鏈表中去。新的鉤子將加到老的前面。當一個事件發(fā)生時,如果您安裝的是一個局部鉤子,您進程中的鉤子函數(shù)將被調(diào)用。如果是一個遠程鉤子,系統(tǒng)就必須把鉤子函數(shù)插入到其它進程的地址空間,要做到這一點要求鉤子函數(shù)必須在一個動態(tài)鏈接庫中,所以如果您想要使用遠程鉤子,就必須把該鉤子函數(shù)放到動態(tài)鏈接庫中去。當然有兩個例外:工作日志鉤子和工作日志回放鉤子。這兩個鉤子的鉤子函數(shù)必須在安裝鉤子的線程中。原因是:這兩個鉤子是用來監(jiān)控比較底層的硬件事件的,既然是記錄和回放,所有的事件就當然都是有先后次序的。所以如果把回調(diào)函數(shù)放在DLL中,輸入的事件被放在幾個線程中記錄,所以我們無法保證得到正確的次序。故解決的辦法是:把鉤子函數(shù)放到單個的線程中,譬如安裝鉤子的線程。
鉤子一共有14種,以下是它們被調(diào)用的時機:
WH_CALLWNDPROC 當調(diào)用SendMessage時
WH_CALLWNDPROCRET 當SendMessage的調(diào)用返回時
WH_GETMESSAGE 當調(diào)用GetMessage 或 PeekMessage時
WH_KEYBOARD 當調(diào)用GetMessage 或 PeekMessage 來從消息隊列中查詢WM_KEYUP 或 WM_KEYDOWN 消息時
WH_MOUSE 當調(diào)用GetMessage 或 PeekMessage 來從消息隊列中查詢鼠標事件消息時
WH_HARDWARE 當調(diào)用GetMessage 或 PeekMessage 來從消息隊列種查詢非鼠標、鍵盤消息時
WH_MSGFILTER 當對話框、菜單或滾動條要處理一個消息時。該鉤子是局部的。它時為那些有自己的消息處理過程的控件對象設(shè)計的。
WH_SYSMSGFILTER 和WH_MSGFILTER一樣,只不過是系統(tǒng)范圍的
WH_JOURNALRECORD 當WINDOWS從硬件隊列中獲得消息時
WH_JOURNALPLAYBACK 當一個事件從系統(tǒng)的硬件輸入隊列中被請求時
WH_SHELL 當關(guān)于WINDOWS外殼事件發(fā)生時,譬如任務條需要重畫它的按鈕.
WH_CBT 當基于計算機的訓練(CBT)事件發(fā)生時
WH_FOREGROUNDIDLE 由WINDOWS自己使用,一般的應用程序很少使用
WH_DEBUG 用來給鉤子函數(shù)除錯
附:如何使用鉤子函數(shù)(接收到字母A按下時,窗體由最小化彈出的完整的代碼)
Public Declare Function CallNextHookEx Lib "user32" _
(ByVal hHook As Long, _
ByVal nCode As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) As Long
Public Declare Function UnhookWindowsHookEx Lib "user32" _
(ByVal hHook As Long) As Long
Public Declare Function SetWindowsHookEx Lib "user32" _
Alias "SetWindowsHookExA" _
(ByVal idHook As Long, _
ByVal lpfn As Long, _
ByVal hmod As Long, _
ByVal dwThreadId As Long) As Long
Public Const WH_KEYBOARD = 2
Public Const KEY_WINSTART = 91
Public Const KEY_WINMENU = 93
Global hHook As Long
Public Function KeyboardProc(ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
If nCode = 0 Then
If wParam = KEY_WINMENU Or wParam = KEY_WINSTART Then
If (lParam And HC0000000) = 0 Then
MsgBox "", , ""
KeyboardProc = 1
Exit Function
End If
End If
End If
KeyboardProc = CallNextHookEx(hHook, nCode, wParam, lParam)
End Function
Option Explicit
Private Sub Command1_Click()
form2.Show 1
End Sub
Private Sub form_Load()
hHook = SetWindowsHookEx(WH_KEYBOARD, AddressOf KeyboardProc, 0, App.ThreadID)
Me.Show
End Sub
Private Sub form_Unload(Cancel As Integer)
Call UnhookWindowsHookEx(hHook)
End Sub
大大提供了靈活性。
@before_first_request
在對應用程序?qū)嵗牡谝粋€請求之前注冊要運行的函數(shù),只會運行一次
@before_request
在每個請求之前注冊一個要運行的函數(shù),每一次請求都會執(zhí)行一次
@after_request
在每個請求之后注冊一個要運行的函數(shù),每次請求完成后都會執(zhí)行。
需要接受一個Response對象作為參數(shù),并返回一個新的Response對象,或者返回接收的Response對象
@teardown_request
注冊在每一個請求的末尾,不管是否有異常,每次請求的最后都會執(zhí)行。
@context_processor
上下文處理器,返回的字典可以在全部的模板中使用
@template_filter('xxxxxx')
增加模板過濾器,可以在模板中使用該函數(shù),后面的參數(shù)是名稱,在模板中用到
@errorhandler(400)
發(fā)生一些異常時,比如404,500,或者拋出異常(Exception)之類的,就會自動調(diào)用該鉤子函數(shù)
1.發(fā)生請求錯誤時,框架會自動調(diào)用相應的鉤子函數(shù),并向鉤子函數(shù)中傳入error參數(shù)
2.如果鉤子函數(shù)沒有定義error參數(shù),就會報錯
3.可以使用abort函數(shù)來手動終止請求拋出異常,如果要是發(fā)生參數(shù)錯誤,可以abort(404)之類的
a. app.py
b. hooks.py
c. main.py
看別人的寫法,創(chuàng)建hooks.py后,直接在該文件import app后,然后寫鉤子函數(shù),在訪問過程中鉤子函數(shù)是生效,但我一直失敗,沒辦法只能更改寫法了。
先在app.py中創(chuàng)建app對象,然后在hooks.py中import app寫好鉤子函數(shù),最后在main.py中import app時不再是從app.py中了,而是從hooks.py中import,那么在這個過程中hooks.py文件就加載了,鉤子函數(shù)也就生效了。