寫一個類. 類里留個變量(fun2_tiime)記錄函數(shù)2執(zhí)行的時間戳.
創(chuàng)新互聯(lián)公司專注于企業(yè)全網(wǎng)營銷推廣、網(wǎng)站重做改版、婁煩網(wǎng)站定制設(shè)計、自適應(yīng)品牌網(wǎng)站建設(shè)、H5頁面制作、成都商城網(wǎng)站開發(fā)、集團(tuán)公司官網(wǎng)建設(shè)、成都外貿(mào)網(wǎng)站建設(shè)公司、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計等建站業(yè)務(wù),價格優(yōu)惠性價比高,為婁煩等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。
類里寫個無限循環(huán)的函數(shù), 不斷比較 變量(fun2_tiime)當(dāng)前時間差值, 如果差值大于20就執(zhí)行函數(shù)2.
#?encoding:?UTF-8
#?系統(tǒng)模塊
from?Queue?import?Queue,?Empty
from?threading?import?*
########################################################################
class?EventManager:
#----------------------------------------------------------------------
def?__init__(self):
"""初始化事件管理器"""
#?事件對象列表
self.__eventQueue?=?Queue()
#?事件管理器開關(guān)
self.__active?=?False
#?事件處理線程
self.__thread?=?Thread(target?=?self.__Run)
#?這里的__handlers是一個字典,用來保存對應(yīng)的事件的響應(yīng)函數(shù)
#?其中每個鍵對應(yīng)的值是一個列表,列表中保存了對該事件監(jiān)聽的響應(yīng)函數(shù),一對多
self.__handlers?=?{}
#----------------------------------------------------------------------
def?__Run(self):
"""引擎運(yùn)行"""
while?self.__active?==?True:
try:
#?獲取事件的阻塞時間設(shè)為1秒
event?=?self.__eventQueue.get(block?=?True,?timeout?=?1)??
self.__EventProcess(event)
except?Empty:
pass
#----------------------------------------------------------------------
def?__EventProcess(self,?event):
"""處理事件"""
#?檢查是否存在對該事件進(jìn)行監(jiān)聽的處理函數(shù)
if?event.type_?in?self.__handlers:
#?若存在,則按順序?qū)⑹录鬟f給處理函數(shù)執(zhí)行
for?handler?in?self.__handlers[event.type_]:
handler(event)
#----------------------------------------------------------------------
def?Start(self):
"""啟動"""
#?將事件管理器設(shè)為啟動
self.__active?=?True
#?啟動事件處理線程
self.__thread.start()
#----------------------------------------------------------------------
def?Stop(self):
"""停止"""
#?將事件管理器設(shè)為停止
self.__active?=?False
#?等待事件處理線程退出
self.__thread.join()
#----------------------------------------------------------------------
def?AddEventListener(self,?type_,?handler):
"""綁定事件和監(jiān)聽器處理函數(shù)"""
#?嘗試獲取該事件類型對應(yīng)的處理函數(shù)列表,若無則創(chuàng)建
try:
handlerList?=?self.__handlers[type_]
except?KeyError:
handlerList?=?[]
self.__handlers[type_]?=?handlerList
#?若要注冊的處理器不在該事件的處理器列表中,則注冊該事件
if?handler?not?in?handlerList:
handlerList.append(handler)
#----------------------------------------------------------------------
def?RemoveEventListener(self,?type_,?handler):
"""移除監(jiān)聽器的處理函數(shù)"""
#讀者自己試著實(shí)現(xiàn)
#----------------------------------------------------------------------
def?SendEvent(self,?event):
"""發(fā)送事件,向事件隊列中存入事件"""
self.__eventQueue.put(event)
########################################################################
"""事件對象"""
class?Event:
def?__init__(self,?type_=None):
self.type_?=?type_??????#?事件類型
self.dict?=?{}??????????#?字典用于保存具體的事件數(shù)據(jù)
測試代碼
#?encoding:?UTF-8
import?sys
from?datetime?import?datetime
from?threading?import?*
from?EventManager?import?*
#事件名稱??新文章
EVENT_ARTICAL?=?"Event_Artical"
#事件源?公眾號
class?PublicAccounts:
def?__init__(self,eventManager):
self.__eventManager?=?eventManager
def?WriteNewArtical(self):
#事件對象,寫了新文章
event?=?Event(type_=EVENT_ARTICAL)
event.dict["artical"]?=?u'如何寫出更優(yōu)雅的代碼\n'
#發(fā)送事件
self.__eventManager.SendEvent(event)
print?u'公眾號發(fā)送新文章\n'
#監(jiān)聽器?訂閱者
class?Listener:
def?__init__(self,username):
self.__username?=?username
#監(jiān)聽器的處理函數(shù)?讀文章
def?ReadArtical(self,event):
print(u'%s?收到新文章'?%?self.__username)
print(u'正在閱讀新文章內(nèi)容:%s'??%?event.dict["artical"])
"""測試函數(shù)"""
#--------------------------------------------------------------------
def?test():
listner1?=?Listener("thinkroom")?#訂閱者1
listner2?=?Listener("steve")#訂閱者2
eventManager?=?EventManager()
#綁定事件和監(jiān)聽器響應(yīng)函數(shù)(新文章)
eventManager.AddEventListener(EVENT_ARTICAL,?listner1.ReadArtical)
eventManager.AddEventListener(EVENT_ARTICAL,?listner2.ReadArtical)
eventManager.Start()
publicAcc?=?PublicAccounts(eventManager)
timer?=?Timer(2,?publicAcc.WriteNewArtical)
timer.start()
if?__name__?==?'__main__':
test()
應(yīng)該是給一個標(biāo)簽綁定多個事件監(jiān)聽函數(shù)吧?
addEventListener 可以重復(fù)綁定多個
不會有沖突 按照綁定先后的順序去執(zhí)行多個函數(shù)。
def?write_log(username,operation):
'''
寫日志函數(shù)
:param?username:用戶名
:param?operation:用戶的操作信息
:return:
'''
w_time?=?time.strftime('%Y-%m-%d?%H%M%S')
with?open('log.txt','a+')?as?fw:
log_content?=?'%s?%s?%s?\n'%(w_time,username,operation)
fw.write(log_content)
希望對你有幫助!
gevent 比起其他框架(比如tornado,twisted)的一個巨大優(yōu)勢就是:用同步的方法(自然沒有回調(diào)函數(shù))寫異步應(yīng)用,因?yàn)橥降姆绞礁咏_發(fā)人員的編程思維。
gevent可以用一句話向pythoner闡述:使用多路IO復(fù)用對文件描述符的事件監(jiān)聽,從而撬動協(xié)程的“透明”切換。這句話說起來容易,但是闡述起來就復(fù)雜些:
底層(或者說主協(xié)程)自然有一個多路IO復(fù)用循環(huán)(linux上是epoll,unix是kqueue,以下統(tǒng)一用epoll代替描述)
當(dāng)處理一個socket鏈接時,就創(chuàng)建一個協(xié)程greenlet去處理。
當(dāng)socket遇到阻塞的時候,比如等待數(shù)據(jù)的返回或者發(fā)送,此時gevent做了很關(guān)鍵的兩步:
為這個socket的fd在epoll上添加可讀或者可寫事件回調(diào),而這個回調(diào)函數(shù)便是 gevent.getcurrent().switch
通過 get_hub().switch() 切換到主協(xié)程。切換回主協(xié)程,去干其他事情了。但是當(dāng)該socket可讀或者可寫,epoll自然會調(diào)用上述添加的回調(diào)函數(shù),從而切換回socket的處理協(xié)程,從上次懸掛點(diǎn)接著往下執(zhí)行。
之所以做到透明,是因?yàn)閜ython socket上打了patch。所謂打patch,就是自己實(shí)現(xiàn)了一個socket模塊替換了python的標(biāo)準(zhǔn)socket模塊。