本文翻譯自The Flask Mega-Tutorial Part I: Hello, World!
一趟愉快的學習之旅即將開始,跟隨它你將學會用Python和Flask來創建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
)。預期的輸出如下:
1 $ python3 2 Python 3.5.2 (default, Nov 17 2016, 17:05:23) 3 [GCC 5.4.0 20160609] on linux 4 Type "help", "copyright", "credits" or "license" for more information. 5 >>> _
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
命令如下:
1 $ 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:
1 $ mkdir microblog 2 $ cd microblog
如果你正在使用Python3,虛擬環境已經成為內置模塊,可以直接通過如下命令來創建它:
1 $ 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,你可以使用以下命令創建一個虛擬環境:
1 $ virtualenv venv
不管你用什么方法創建虛擬環境,創建完畢之后還需要激活才能夠進入這個虛擬環境。 要激活你的全新虛擬環境,需使用以下命令:
1 $ source venv/bin/activate 2 (venv) $ _
如果你使用的是Microsoft Windows命令提示符窗口,則激活命令稍有不同:
1 $ venv\Scripts\activate 2 (venv) $ _
激活一個虛擬環境,終端會話的環境配置就會被修改,之后你鍵入python
的時候,實際上是調用的虛擬環境中的Python解釋器。 此外,終端提示符也被修改成包含被激活的虛擬環境的名稱的格式。這種激活是臨時的和私有的,因此在關閉終端窗口時它們將不會保留,也不會影響其他的會話。 那么,當你需要同時打開多個終端窗口來調試不同的應用時,每個終端窗口都可以激活不同的虛擬環境而不會相互影響。
成功創建和激活了虛擬環境之后,你可以安裝Flask了,命令如下:
1 (venv) $ pip install flask
想要驗證安裝是否成功,可以打開Python解釋器,並用import語句來導入它:
1 >>> import flask 2 >>> _
如果語句沒有報錯,那么恭喜你,Flask安裝成功了!
“Hello, World” Flask應用
Flask網站展示了一個僅有五行代碼的簡單示例應用程序。 而我會告訴你一個稍微更復雜的例子,它將為你編寫更大的應用程序提供一個很好的基礎結構。
應用程序是存在於包中的。 在Python中,包含__init__.py
文件的子目錄被視為一個可導入的包。 當你導入一個包時,__init__.py
會執行並定義這個包暴露給外界的屬性。
那就創建一個名為app
的包來存放整個應用吧。記得切換到microblog目錄下,並執行如下命令:
1 (venv) $ mkdir app
並在其下創建文件__init__.py
,輸入如下的代碼:
1 from flask import Flask 2 app = Flask(__name__) 3 from app import routes
上面的腳本僅僅是從flask中導入的類Flask
,並以此類創建了一個應用程序對象。 傳遞給Flask
類的__name__
變量是一個Python預定義的變量,它表示當前調用它的模塊的名字。當需要加載相關的資源,如我將在第二章講到的模板文件,Flask就使用這個位置作為起點來計算絕對路徑。 代碼的最后,應用程序導入尚未存在的routes
模塊。
這段代碼,乍一看可能會讓人迷惑。
其一,這里有兩個實體名為app
。 app
包由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中的第一個視圖函數的代碼:
1 from app import app 2 3 @app.route('/') 4 @app.route('/index') 5 def index(): 6 return "Hello, World!"
這個視圖函數簡單到只返回一個字符串作為問候用語。 函數上面的兩個奇怪的@app.route
行是裝飾器,這是Python語言的一個獨特功能。 裝飾器會修改跟在其后的函數。 裝飾器的常見模式是使用它們將函數注冊為某些事件的回調函數。 在這種情況下,@app.route
修飾器在作為參數給出的URL和函數之間創建一個關聯。 在這個例子中,有兩個裝飾器,它們將URL /
和/index
索引關聯到這個函數。 這意味着,當Web瀏覽器請求這兩個URL中的任何一個時,Flask將調用該函數並將其返回值作為響應傳遞回瀏覽器。這樣做是為了在運行這個應用程序的時候會稍微有一點點意義。
要完成應用程序,你需要在定義Flask應用程序實例的頂層(譯者注:也就是microblog目錄下)創建一個命名為microblog.py的Python腳本。 它僅擁有一個導入應用程序實例的行:
1 from app import app
還記得兩個app
實體嗎? 在這里,你可以在同一句話中看到兩者。 Flask應用程序實例被稱為app
,是app
包的成員。from app import app
語句從app
包導入其成員app
變量。 如果你覺得這很混亂,你可以重命名包或者變量。
只要確保所做的操作完全正確,那么你就可以看到如下面的項目結構圖:
1 microblog/ 2 venv/ 3 app/ 4 __init__.py 5 routes.py 6 microblog.py
不管你信不信,這個應用的第一個版本現在完成了! 但是在運行之前,需要通過設置FLASK_APP
環境變量告訴Flask如何導入它:
1 (venv) $ export FLASK_APP=microblog.py
如果你使用Microsoft Windows操作系統,在上面的命令中使用set
替換export
。
萬事俱備,只欠東風!運行如下命令來運行你的第一個Web應用吧:
1 (venv) $ flask run 2 * Serving Flask app "microblog" 3 * 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被應用程序識別。
完成演示之后,你可以按下Ctrl-C來停止Web服務。
真是可喜可賀!你已經成功地向成為一名Web開發者的道路上邁出了重要的第一步!