Flask教程第一章:Hello,World!

天降攻城獅發表於2019-02-22

本文轉載自:https://www.jianshu.com/p/fcbd137f308b

一趟愉快的學習之旅即將開始,跟隨它你將學會用PythonFlask來建立Web應用。上面的視訊包含了整個教程的內容預覽(譯者注:視訊見原文)。通過學習本章內容,你將學會如何建立一個Flask專案,並在自己的電腦上執行一個簡單的Flask Web應用。

教程中所有的程式碼示例都託管在GitHub上。雖然直接從GitHub下載程式碼可以節省寫程式碼的步驟,但是我強烈建議你至少在前幾章自己動手書寫這些程式碼。一旦你熟悉了Flask和示例應用,一些繁瑣重複的程式碼就可以直接從GitHub複製了。

在每章的開頭,我都將提供三個GitHub的連結來幫助你順暢地學習本章的內容。點選Browse連結會開啟GitHub上Microblog專案在本章的對應程式碼庫頁面,不會包含之後章節的任何新增程式碼。而Zip連結則提供了這份程式碼庫的zip打包檔案的下載地址。如果點選Diff連結,開啟的將會是本章節的程式碼變更資訊。

本章的GitHub連結為: Browse, Zip, Diff.

安裝Python

你說你還沒有安裝Python?那還等什麼!立馬安裝吧。如果作業系統預設沒有提供Python安裝包,可以從Python官方網站下載。如果你使用Microsoft Windows作業系統並且打算使用WSL或者Cygwin,需要注意,不要在上面使用Windows版本的Python,而要使用類Unix版本,比如從Ubuntu獲取(對應WSL)或從Cygwin上獲取。

為了驗證Python是否正確安裝,你可以開啟一個終端視窗並輸入python3(如果不存在這個命令,那就輸入python)。預期的輸出如下:

$ python3
Python 3.5.2 (default, Nov 17 2016, 17:05:23)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> _

Python直譯器中,游標不斷閃爍,等待著你輸入Python語句。在未來的章節中,你可以充分體會到互動式直譯器的魅力。至少現在它能夠幫你確認Python已經成功安裝的事實。可以輸入exit()並回車來退出互動式直譯器。在Linux和Mac OS X作業系統上,按下快捷鍵Ctrl-D也可以快速退出互動式直譯器。在Windows作業系統上,則是通過按下Ctrl-Z後跟上Enter快捷鍵來快速退出。

安裝Flask

下一步開始安裝Flask,在這之前我要告訴你安裝Python三方包的最佳實踐。

Python將所有三方包託管到一個公共倉庫,任何人都能從這個公共倉庫下載並安裝所有的三方包。Python將三方包公共倉庫命名為PyPI以表示Python Package Index的縮寫(被一些人戲稱為”cheese shop”)。從PyPI上安裝三方包非常簡單,Python專門提供了一個名為pip的工具來解決這個問題(Python2.7中不含pip工具,需要單獨安裝)。

安裝三方包時,使用pip命令如下:

$ pip install <package-name>

有趣的是,這個方法在大多數情況下不適用。假如Python直譯器是全域性安裝的,所有使用者都能使用,那麼普通使用者則沒有許可權來修改它,因此只能用管理員賬戶來執行安裝操作。即使忽略操作的複雜性,使用這種全域性安裝的方式會發生什麼?pip工具從PyPI上下載三方包並安裝到全域性Python目錄下,即刻起,所有Python指令碼都可以訪問到這個三方包。想象這樣一個場景,你之前用當時的最新版本Flask——0.11版本的Flask開發了一個Web應用,現在Flask已經更新到了0.12版本,你想要使用0.12版本的Flask開發第二個Web應用。但是,如果將Flask從0.11版本升級到0.12版本可能會導致第一個Web應用出現故障。解決這個問題的方法最好不過為舊Web應用安裝和使用Flask0.11版本,為新Web應用安裝和使用Flask0.12版本。

為了解決維護不同應用程式對應不同版本的問題,Python使用了虛擬環境的概念。 虛擬環境是Python直譯器的完整副本。在虛擬環境中安裝三方包時只會作用到虛擬環境,全域性Python直譯器不受影響。 那麼,就為每個應用程式安裝各自的虛擬環境吧。 虛擬環境還有一個好處,即它們由建立它們的使用者所擁有,所以不需要管理員帳戶。

我們先建立專案目錄,我將這個應用命名為microblog

$ mkdir microblog
$ cd microblog

如果你正在使用Python3,虛擬環境已經成為內建模組,可以直接通過如下命令來建立它:

$ python3 -m venv venv

譯者注:這個命令不一定能夠執行成功,比如譯者在Ubuntu16.04環境下執行,提示需要先安裝對應的依賴。sudo apt-get install python3-venv

使用這個命令來讓Python執行venv包,它會建立一個名為venv的虛擬環境。 命令中的第一個“venv”是Python虛擬環境包的名稱,第二個是要用於這個特定環境的虛擬環境名稱。 如果你覺得這樣很混亂,可以用你自定義的虛擬環境名字替換第二個venv。我習慣在專案目錄中建立了名為venv的虛擬環境,所以無論何時cd到一個專案中,都會找到相應的虛擬環境。

請注意,在一些作業系統中,你可能需要在上面的命令中使用python而不是python3。 一些安裝規範對Python 2.x版本使用python,對3.x版本使用python3,而另一些則將python對映到3.x版本。

命令執行完成後,當前目錄下就會新增一個名為venv的目錄來儲存這個虛擬環境的相關檔案。

如果你使用的Python版本低於3.4(包括2.7版本),則不會預設支援虛擬環境。 對於這些版本的Python,在建立虛擬環境之前,需要下載並安裝稱為virtualenv的第三方工具。 一旦安裝了virtualenv,你可以使用以下命令建立一個虛擬環境:

$ virtualenv venv

不管你用什麼方法建立虛擬環境,建立完畢之後還需要啟用才能夠進入這個虛擬環境。 要啟用你的全新虛擬環境,需使用以下命令:

$ source venv/bin/activate
(venv) $ _

如果你使用的是Microsoft Windows命令提示符視窗,則啟用命令稍有不同:

$ venvScriptsactivate
(venv) $ _

啟用一個虛擬環境,終端會話的環境配置就會被修改,之後你鍵入python的時候,實際上是呼叫的虛擬環境中的Python直譯器。 此外,終端提示符也被修改成包含被啟用的虛擬環境的名稱的格式。這種啟用是臨時的和私有的,因此在關閉終端視窗時它們將不會保留,也不會影響其他的會話。 那麼,當你需要同時開啟多個終端視窗來除錯不同的應用時,每個終端視窗都可以啟用不同的虛擬環境而不會相互影響。

成功建立和啟用了虛擬環境之後,你可以安裝Flask了,命令如下:

(venv) $ pip install flask

想要驗證安裝是否成功,可以開啟Python直譯器,並用import語句來匯入它:

>>> import flask
>>> _

如果語句沒有報錯,那麼恭喜你,Flask安裝成功了!

“Hello, World” Flask應用

Flask網站展示了一個僅有五行程式碼的簡單示例應用程式。 而我會告訴你一個稍微更復雜的例子,它將為你編寫更大的應用程式提供一個很好的基礎結構。

應用程式是存在於中的。 在Python中,包含__init__.py檔案的子目錄被視為一個可匯入的包。 當你匯入一個包時,__init__.py會執行並定義這個包暴露給外界的屬性。

那就建立一個名為app的包來存放整個應用吧。記得切換到microblog目錄下,並執行如下命令:

(venv) $ mkdir app

並在其下建立檔案__init__.py,輸入如下的程式碼:

from flask import Flask

app = Flask(__name__)

from app import routes

上面的指令碼僅僅是從flask中匯入的類Flask,並以此類建立了一個應用程式物件。 傳遞給Flask類的__name__變數是一個Python預定義的變數,它表示當前呼叫它的模組的名字。當需要載入相關的資源,如我將在第二章講到的模板檔案,Flask就使用這個位置作為起點來計算絕對路徑。 程式碼的最後,應用程式匯入尚未存在的routes模組。

這段程式碼,乍一看可能會讓人迷惑。

其一,這裡有兩個實體名為appapp包由app目錄和__init__.py指令碼來定義構成,並在from app import routes語句中被引用。 app變數被定義為__init__.py指令碼中的Flask類的一個例項,以至於它成為app包的屬性。

其二,routes模組是在底部匯入的,而不是在指令碼的頂部。 最下面的匯入是解決迴圈匯入的問題,這是Flask應用程式的常見問題。 你將會看到routes模組需要匯入在這個指令碼中定義的app變數,因此將routes的匯入放在底部可以避免由於這兩個檔案之間的相互引用而導致的錯誤。

那麼在routes模組中有些什麼? 路由是應用程式實現的不同URL。 在Flask中,應用程式路由的處理邏輯被編寫為Python函式,稱為檢視函式。 檢視函式被對映到一個或多個路由URL,以便Flask知道當客戶端請求給定的URL時執行什麼邏輯。

這是需要寫入到app/routes.py中的第一個檢視函式的程式碼:

from app import app

@app.route(`/`)
@app.route(`/index`)
def index():
    return "Hello, World!"

這個檢視函式簡單到只返回一個字串作為問候用語。 函式上面的兩個奇怪的@app.route行是裝飾器,這是Python語言的一個獨特功能。 裝飾器會修改跟在其後的函式。 裝飾器的常見模式是使用它們將函式註冊為某些事件的回撥函式。 在這種情況下,@app.route修飾器在作為引數給出的URL和函式之間建立一個關聯。 在這個例子中,有兩個裝飾器,它們將URL //index索引關聯到這個函式。 這意味著,當Web瀏覽器請求這兩個URL中的任何一個時,Flask將呼叫該函式並將其返回值作為響應傳遞迴瀏覽器。這樣做是為了在執行這個應用程式的時候會稍微有一點點意義。

要完成應用程式,你需要在定義Flask應用程式例項的頂層(譯者注:也就是microblog目錄下)建立一個命名為microblog.py的Python指令碼。 它僅擁有一個匯入應用程式例項的行:

from app import app

還記得兩個app實體嗎? 在這裡,你可以在同一句話中看到兩者。 Flask應用程式例項被稱為app,是app包的成員。from app import app語句從app包匯入其成員app變數。 如果你覺得這很混亂,你可以重新命名包或者變數。

只要確保所做的操作完全正確,那麼你就可以看到如下面的專案結構圖:

microblog/
  venv/
  app/
    __init__.py
    routes.py
  microblog.py

不管你信不信,這個應用的第一個版本現在完成了! 但是在執行之前,需要通過設定FLASK_APP環境變數告訴Flask如何匯入它:

(venv) $ export FLASK_APP=microblog.py

如果你使用Microsoft Windows作業系統,在上面的命令中使用set替換export

萬事俱備,只欠東風!執行如下命令來執行你的第一個Web應用吧:

(venv) $ flask run
 * Serving Flask app "microblog"
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

服務啟動後將處於阻塞監聽狀態,將等待客戶端連線。 flask run的輸出表明伺服器正在執行在IP地址127.0.0.1上,這是本機的迴環IP地址。 這個地址很常見,並有一個更簡單的名字,你可能已經看過:localhost。 網路伺服器監聽在指定埠號等待連線。 部署在生產Web伺服器上的應用程式通常會在埠443上進行監聽,如果不執行加密,則有時會監聽80,但啟用這些埠需要root許可權。 由於此應用程式在開發環境中執行,因此Flask使用自由埠5000。 現在開啟您的網路瀏覽器並在位址列中輸入以下URL:

    http://localhost:5000/

或者,你也可以使用另一個URL:

    http://localhost:5000/index

應用程式路由對映執行了嗎? 第一個URL對映到/,而第二個對映到/ index。 這兩個路由都與應用程式中唯一的檢視函式相關聯,所以它們產生相同的輸出,即函式返回的字串。 如果你輸入任何其他網址,則會出現錯誤,因為只有這兩個URL被應用程式識別。

Hello, World!

完成演示之後,你可以按下Ctrl-C來停止Web服務。

真是可喜可賀!你已經成功地向成為一名Web開發者的道路上邁出了重要的第一步!