sanic
是乙個可以使用async
/await語法編寫專案的非同步非阻塞框架,它寫法類似於flask
,但使用了非同步特性,而且還使用uvloop
作為事件迴圈,其底層使用的是libuv
,從而使sanic
的速度優勢更加明顯。
本章,我將和大家一起看看sanic
裡面的執行機制是怎樣的,它的router
blueprint等是如何實現的。
sanic-0.1.2 的核心檔案如下:
.
├── __init__.py
├── blueprints.py
├── config.py
├── exceptions.py
├── log.py
├── request.py
├── response.py
├── router.py
├── sanic.py
├── server.py
└── utils.py
通過執行下面的示例,這些檔案都會被我們看到它的作用,拭目以待吧,為了方便諸位的理解,我已將我註解的乙份sanic
**上傳到了github
,見sanic_annotation。
讓我們從******_server開始吧,**如下:
from sanic_0_1_2.src import sanic
from sanic_0_1_2.src.response import json
async def test(request):
return json()
或許你直接把sanic_annotation專案直接clone到本地比較方便除錯+理解:
git clone那麼,現在一切準備就緒,開始閱讀吧。cd sanic_annotation/sanic_0_1_2/examples/
前兩行**匯入包:
例項化乙個sanic
=sanic
(__name__
),可見sanic.py,我已經在這個檔案裡面做了一些注釋,這裡也詳細說下sanic
類:
其實上面這部分介紹已經講了sanic基本的執行邏輯,如果你理解了,那下面的講解對你來說是輕輕鬆鬆,如果不怎麼明白,也不要緊,這是只是乙個大體的介紹,跟著步驟來,也很容易理解,繼續看**:
# 此處將路由 / 與檢視函式 test 關聯起來
async def test(request):
return json()
.
route
,上面介紹過,隨著sanic服務的啟動而啟動,可定義引數uri
,methods
目的是為url
的path
和檢視函式對應起來,構建一對對映關係,本例中sanic
.router類下的router
.routes
=
會增加乙個名為route
的namedtuple
,如下:
[route(handler=, methods=none, pattern=re.compile('^/$'), parameters=)]
看到沒,uri
'/'
和檢視函式test
對應起來了,如果客戶端請求'/'
,當伺服器監聽到這個請求的時候,handle_request
可以通過引數中的request
.url
來找到檢視函式test
並且執行,隨即生成檢視返回
那麼這裡write_response
就會接受檢視函式test返回的json
()
說下router
類,這個類的目的就是新增和獲取路由對應的檢視函式,把它想象成dict
或許更容易理解:
.run
(host
="0.0.0.0"
,port
=8000
),sanic 下的run
函式,啟動乙個http server
,主要是啟動run
裡面的serve
函式,引數如下:
try:
serve(
host=host,
port=port,
debug=debug,
# 服務開始後啟動的函式
after_start=after_start,
# 在服務關閉前啟動的函式
before_stop=before_stop,
# sanic(__name__).handle_request()
request_handler=self.handle_request,
# 預設讀取config
request_timeout=self.config.request_timeout,
request_max_size=self.config.request_max_size,
) except:
pass
讓我們將目光投向server.py,這也是sanic框架的核心**:
至此,sanic 服務啟動了
不要小看這乙個小小的demo,執行一下,竟然涉及到下面這麼多個檔案,讓我們總結一下:
除去__init__
.py,sanic
專案一共就10個檔案,這個小demo不顯山不露水地竟然用到了8個,雖然其中幾個沒有怎麼用到,但也足夠說明,你如果理解了這個demo,sanic
的執行邏輯以及框架**你已經了解地很深入了
這個例子看完,我們就能輕易地明白什麼是blueprints
,以及blueprints
的執行方式,**如下:
from sanic_0_1_2.src import sanic
# 引入blueprint
from sanic_0_1_2.src import blueprint
from sanic_0_1_2.src.response import json, text
blueprint = blueprint('name', url_prefix='/my_blueprint')
blueprint2 = blueprint('name2', url_prefix='/my_blueprint2')
@blueprint.route('/foo')
async def foo(request):
return json()
@blueprint2.route('/foo')
async def foo2(request):
return json()
讓我們從這兩行開始:
blueprint = blueprint('name', url_prefix='/my_blueprint')顯然,blueprint2 = blueprint('name2', url_prefix='/my_blueprint2')
blueprint
以及blueprint2
是blueprint
根據不同的引數生成的不同的例項物件,接下來要幹嘛?沒錯,分析blueprints.py:
請看下route
和register
函式,然後再看下面的**:
# 生成乙個匿名函式到self.deferred_functions列表裡 包含三個引數 handler(foo), uri, methods
@blueprint.route('/foo')
async def foo(request):
return json()
@blueprint2.route('/foo')
async def foo2(request):
return json()
# 上乙個例子說過這個函式,sanic().register_blueprint() 註冊藍圖
.
run(
host
="0.0.0.0"
,port
=8000
,debug
=true
)服務啟動**不用多說吧?
看到這裡,相信你已經完全理解了sanic
的執行機制,雖然還有middleware
&exception的註冊以及呼叫機制沒講,但這和route
的執行機制一樣,如果你懂了route
那麼這兩個也很簡單。
如果諸位一遍沒怎麼看明白,這裡我建議可以多看幾遍,多結合編輯器debug
下原始碼,堅持下來,會發下sanic
真的很簡單,當然,這只是第乙個小版本的sanic
,和目前的版本相比,不論是**結構的複雜程度以及功能對比,都有很大差距,畢竟,sanic
一直在開源工作者的努力下,慢慢成長。
本人技術微末,若有錯誤,請指出,不勝感激.
原始碼剖析 Hashtable 原始碼剖析
hashtable同樣是基於雜湊表實現的,同樣每個元素都是key value對,其內部也是通過單鏈表解決衝突問題,容量不足 超過了閾值 時,同樣會自動增長。hashtable也是jdk1.0引入的類,是執行緒安全的,能用於多執行緒環境中。hashtable同樣實現了serializable介面,它支...
python原始碼剖析 Python原始碼剖析
第頁共 頁python 原始碼剖析 物件機制 1.物件 在python 的世界中,一切都是物件,乙個整數是乙個物件,乙個字串也是 乙個物件,更為奇妙的是,型別也是乙個物件,整數型別是乙個物件,字串類 型也是乙個物件。從 年guido 在那個聖誕節揭開 python 世界的大幕開始,一直到現在,pyt...
Erlang hotwheels原始碼剖析
整體構架 janus transport sup 實質為transport,supervisor,client instance supervisor 每個tcp會話建立乙個transport程序來處理對應客戶端的請求。janus topman sup 實質為topman,worker,topic ...