今天有足夠多的時間來看看Tornado中RequestHandler和Application這兩個類的關系。
昨天想要調用settings中的內容,找了好半天不知道怎么在handler中使用settings,后來一點一點試出來了,哈哈。比如一個類:
class HelloHandler(tornado.web.RequestHandler):
def get(self): path = self.application.settings["static_path"] self.write(path) self.finish()
由此我們知道tornado.web.Application是作為參數傳入到了tornado.web.RequestHandler中。去看一下源代碼先
class RequestHandler(object):
。。。
def __init__(self, application, request, **kwargs): super(RequestHandler, self).__init__() self.application = application self.request = request 。。。
而tornado.web.Application同樣有着指向RequestHandler的指針(可以這么理解的)。
讓我們繼續看看IOloop這個類是如何工作的。
地一個方法絕對就是instance(cls)這個類方法。
@classmethod
def instance(cls): if not hasattr(cls,"_instance") _instance = cls() return _instance
我想在這里再次說一下實例方法,類方法和靜態方法的區別:
首先實例方法和類方法,是有一個特別的參數的,self或者cls,當然這不是關鍵字我們可以使用其他的來代替。當一個實例即使調用了類方法,這個方法的第一參數傳入的仍為類。
而如果一個類調用了實例方法那是會報錯的。
這個instance是一個類似單例的一個模式。返回一個IOloop的實例。調用start()方法將底層的mulitplex模型跑起來,正是這種模型才能保證tornado有着很高的處理效率。這里重點看一下是如何與http_server相關聯起來的。可是代碼找了半天根本沒有提到httpserver'的事情只是不斷的在update events然后再對event進行處理。
我們來到httpserver .py這里看看這里是否有和ioloop有關的代碼。可以看到在httpserver中是import ioloop,並且在start()方法中調用了instance方法。可是在demo中的helloworld並沒有瞧見有誰調用了httpserver的start()方法。在繼續找…… 在httpserver中的listen函數中發現自己調用了自己的start方法,這樣就齊了。
我們開始看一下helloworld中的main方法。
application = tornado.web.Application([ (r"/", MainHandler), ]) http_server = tornado.httpserver.HTTPServer(application) //這里對handler進行注冊 http_server.listen(options.port) //這里啟動了httpserver tornado.ioloop.IOLoop.instance().start() //這里啟動了ioloop
在httpserver的start方法中也可以看出httpserver收集來的事件將會傳遞給ioloop進行處理。未完……