色婷婷狠狠18禁久久YY,CHINESE性内射高清国产,国产女人18毛片水真多1,国产AV在线观看

如何改寫一個Python庫為異步庫?

錢淋西2年前14瀏覽0評論

Tornado框架的異步非阻塞特性是其最大的亮點,這里我們將立足于基礎來介紹一種簡單的Python的Tornado框架實現異步非阻塞訪問數據庫的示例:

tornado即是一個http非阻塞服務器,就要用起來,我們將用到tornado框架,mongodb數據庫以及motor(mongodb的異步驅動).來簡單實現tornado的非阻塞功能.

其他環境支持的下載與安裝

1.安裝mongodb

$sudoapt-getinstallupdate$sudoapt-getinstallmongodb

2.安裝motor

$pipinstallmotor

非阻塞

#conf.pyimportosimportmotorfromhandlersimportindex,authBASE_DIR=os.path.join(__file__)handlers=[(r'^/$',index.IndexHandler),(r'^/auth/register$',auth.RegisterHandler),(r'^/auth/login$',auth.LoginHandler),]settings=dict(debug=True,template_path=os.path.join(BASE_DIR,'templates'),static_path=os.path.join(BASE_DIR,'static'),)client=motor.MotorClient("127.0.0.1")db=client.meet

首先在配置文件中連接數據庫,client.db_name中db_name就是數據庫的名稱

#handlers/__init__.pyclassBaseHandler(tornado.web.RequestHandler,TemplateRendering):definitialite(self):...@propertydefdb(self):returnself.application.db

添加db()并使用property裝飾,像屬性一樣訪問數據庫.

#auth.pyimportosimporttimeimporttornado.webfromtornadoimportgenfrom.importBaseHandlerclassRegisterHandler(BaseHandler):defget(self):self.render_html('register.html')@tornado.web.asynchronous@gen.coroutinedefpost(self):username=self.get_argument('username',None)email=self.get_argument('email',None)password=self.get_argument('password',None)data={'username':username,'email':email,'password':password,'timestamp':time.time()*1000,}ifusernameandemail:yieldself.db.user.insert(data)self.redirect('/')classLoginHandler(BaseHandler):@tornado.web.asynchronous@gen.coroutinedefget(self):username=self.get_argument('useranme')user=yieldself.db.user.find_one({'username':username})self.render_html('login.html',user=user)

@gen.coroutine裝飾使函數非阻塞,返回一個生成器,而不用在使用回調函數.motor也通過yield實現異步(不然還得返回一個回調函數).其實這個例子反映不了阻塞問題關鍵是時間太短.我們修改一下代碼

#之前yieldself.db.user.insert(data)#之后yieldtornado.gen.Task(tornado.ioloop.IOLoop.instance().add_timeout,time.time()+10)

這里通過tornado.ioloop.IOLoop.instance().add_timeout阻塞應用,這是time.sleep的非阻塞實現,如果這里使用time.sleep因為是tornado是單線程會阻塞整個應用所以別的handler也無法訪問.可以看到我在注冊頁面注冊后,在阻塞期間點擊/auth/login直接就訪問了login頁完成非阻塞.

異步下的redirect問題在使用tornado的時候常常遇到一些問題,特將遇到的問題和解決的方法寫出來(這里的感謝一下幫我解答疑惑的pythonista們)

1.問題

我想要實現一個注冊用戶功能,web框架使用tornado數據庫使用mongodb但在注冊時出現Exceptionredirect的錯誤.現貼下代碼:

classRegister(BaseHandler):defget(self):self.render_html('register.html')@tornado.web.aynchronous@gen.coroutinedefpost(self):username=self.get_argument('username')email=self.get_argument('email')password=self.get_argument('password')captcha=self.get_argument('captcha')_verify_username=yieldself.db.user.find_one({'username':username})if_verify_username:self.flash(u'用戶名已存在','error')self.redirect('/auth/register')_verify_email=yieldself.db.user.find_one({'email':email})if_verify_email:self.flash(u'郵箱已注冊','error')self.redirect('/auth/register')ifcaptchaandcaptcha==self.get_secure_cookie('captcha').replace('',''):self.flash(u'驗證碼輸入正確','info')else:self.flash(u'驗證碼輸入錯誤','error')self.redirect('/auth/register')password=haslib.md5(password+self.settings['site']).hexdigest()profile={'headimg':'','site':'','job':'','signature':'','github':'','description':''}user_profile=yieldself.db.profile.insert(profile)user={'username':username,'email':email,'password':password,'timestamp':time.time(),'profile_id':str(user_profile)}yieldself.db.user.insert(user)self.set_secure_cookie('user',username)self.redirect('/')

本想如果用戶驗證碼輸入出錯就跳轉到注冊頁面,但問題是驗證碼出錯也會繼續執行一下代碼.雖然在self.redirect后加上self.finish會終止代碼,但是因為self.redirect函數內已有self.finish所以出現了兩次報出異常終止的代碼.因為以上原因代碼不會被終結,驗證碼出錯用戶還是會注冊.

2.解決方案

returnself.redirect('/auth/register')

self.redirect('/auth/register')return

(1)segmentdefault中熱心用戶rsj217給出的答案self.finish會關掉請求,因為@tornado.web.aynchronous告訴tornado會一直等待請求(長鏈接).self.redirect等于設置了response的headers的location屬性.

(2)segmentdefault中熱心用戶依云給出的答案self.finish當然不會跳出函數,不然請求結束之后還想做些事情怎么辦呢.

3.總結

因為錯把self.finish當做跳出函數出現了以上的問題

  • self.redirect會在request.headers里設置location用于跳轉
  • self.finish會關掉請求,但不會跳出函數