WSGI規範(PEP 3333) 第四部分(常見問題)

這是規範的最後一部分:常見問題。

原規範還有《建議、討論中》、《知識》、《參考文獻》。由於和規範不太相關,就不作翻譯了。

1. 為什麼 environ 必須用字典表示?用字典子類表示會出現什麼問題?

使用字典的理由是,可以最大化伺服器之間的可移植性。替換方案是定義一個字典的子類作為標準的、可移植的介面,其所有方法是 dict 類的方法的子集。然而,實際上,大部分伺服器會找到一個滿足需要的字典即可,因此框架作者們漸漸發現它們希望找到一個可用完整字典特性的字典實現,因為它們通常會需要。但如果某個伺服器選擇不適用字典表示 environ,就會出現互操作性問題,儘管伺服器會盡量和規範保持一致。因此。為了簡化規範和保持一致性,字典就變得非常必要了。

這並不表示伺服器或者框架的開發者們不能增加其他內容(如在 environ 里自定義一些變數)。這恰恰是規範推薦的方法。

2. 為什麼你可以調用 write(),也可以使用 yield 字元串/return迭代對象?使用其中之一不就夠了?

如果只支持迭代方法,當前的一些使用 push 方法的框架就無法兼容;但是如果我們只通過 write() 支持 push 方法,伺服器性能則因為傳輸大文件而下降(工作線程直到當前輸出完成之後,才能開始處理新請求)。因而,我們做出一點妥協,應用框架就可以支持者兩種方法;相應地,伺服器開發者則要比只支持 push方法多做一點工作。

3. close()有什麼用?

當應用對象完成寫操作後,通過 try/finally 塊,應用對象可以確保相關資源得到釋放。但是,如果應用返回的是迭代對象,相關資源要等迭代對象被 gc 回收之後才會釋放。而 close()則使應用對象在請求處理完成之後,釋放相關資源(調用 close()釋放資源)。這也是向前兼容的,支持生成器內部的 try/finally 塊。

4. 為什麼 WSGI 這麼低級(譯者註:CGI 變數相對於應用中的對象是低級的)?我想用高級特性,如 cookies、sessions、持久化。。。

WSGI 不是另一個 Python web 框架。它僅僅是一種讓框架和 web 伺服器通信的方式,反過來也成立。你想要的這些特性應該由框架提供。並且,如果讓你自己創建 WSGI 應用對象,你應該能夠在多數支持 WSGI 的伺服器上運行它。有些伺服器會在 environ 字典中存放額外的信息;去看看伺服器的文檔吧。當然,使用了這些擴展信息的應用很可能不兼容其他支持 WSGI 的伺服器。

5. 為什麼使用 CGI 變數而不是 HTTP 頭?為什麼將他們和 WSGI 定義的變數混用?

相對 CGI 規範,許多現存的 web 框架是沉重的;而現存的 web 伺服器則擅長生成 CGI 變數。Many existing web frameworks are built heavily upon the CGI spec, and existing web servers know how to generate CGI variables. 相反,另一種方法,

In contrast, alternative ways of representing inbound HTTP information are fragmented and lack market share. Thus, using the CGI "standard" seems like a good way to leverage existing implementations. As for mixing them with WSGI variables, separating them would just require two dictionary arguments to be passed around, while providing no real benefits.

6. status 是什麼?能不能用數字200代替 "200 OK"呢?

用200代替"200 OK"會使得伺服器/網關複雜化,因為這會要求它們維護一張數字和消息映射表。然而,對應用或者框架作者來說,輸入消息文本和相應的狀態碼是容易的。現存的框架一般已經有這張表,所以,讓應用/框架來負責這件事,要比伺服器/網關要好。

7. 為什麼 wsgi.run_once 不能保證只運行應用一次?

Because its merely a suggestion to the application that it should "rig for infrequent running". This is intended for application frameworks that have multiple modes of operation for caching, sessions, and so forth. In a "multiple run" mode, such frameworks may preload caches, and may not write e.g. logs or session data to disk after each request. In "single run" mode, such frameworks avoid preloading and flush all necessary writes after each request.

However, in order to test an application or framework to verify correct operation in the latter mode, it may be necessary (or at least expedient) to invoke it more than once. Therefore, an application should not assume that it will definitely not be run again, just because it is called with wsgi.run_once set to True .

8. Feature X (dictionaries, callables, etc.) are ugly for use in application code; why dont we use objects instead?

All of these implementation choices of WSGI are specifically intended to decouple features from one another; recombining these features into encapsulated objects makes it somewhat harder to write servers or gateways, and an order of magnitude harder to write middleware that replaces or modifies only small portions of the overall functionality.

In essence, middleware wants to have a "Chain of Responsibility" pattern, whereby it can act as a "handler" for some functions, while allowing others to remain unchanged. This is difficult to do with ordinary Python objects, if the interface is to remain extensible. For example, one must use __getattr__ or __getattribute__ overrides, to ensure that extensions (such as attributes defined by future WSGI versions) are passed through.

This type of code is notoriously difficult to get 100% correct, and few people will want to write it themselves. They will therefore copy other peoples implementations, but fail to update them when the person they copied from corrects yet another corner case.

Further, this necessary boilerplate would be pure excise, a developer tax paid by middleware developers to support a slightly prettier API for application framework developers. But, application framework developers will typically only be updating one framework to support WSGI, and in a very limited part of their framework as a whole. It will likely be their first (and maybe their only) WSGI implementation, and thus they will likely implement with this specification ready to hand. Thus, the effort of making the API "prettier" with object attributes and suchlike would likely be wasted for this audience.

We encourage those who want a prettier (or otherwise improved) WSGI interface for use in direct web application programming (as opposed to web framework development) to develop APIs or frameworks that wrap WSGI for convenient use by application developers. In this way, WSGI can remain conveniently low-level for server and middleware authors, while not being "ugly" for application developers.

WSGI規範(PEP 3333) 第一部分(概述)

WSGI規範(PEP 3333) 第二部分(細節)

WSGI規範(PEP 3333) 第三部分(實現)


推薦閱讀:

[E0] Python入門
Python 的 Metaclass 有沒有什麼好的 Best Practice 可以學習?
為什麼有人說 Python 的多線程是雞肋呢?

TAG:WSGI | Python | Web开发 |