python練習:你的第一個網站

練習50.你的第一個網站

最後的3個練習將會很難,你需要在他們身上多花一些時間。第一個練習裡你將創建一個簡單的web版本的遊戲。在你開始這節練習以前,你必須已經成功地完成過了《習題 46》的內容,正確安裝了pip,而且學會了如何安裝軟件包以及如何創建項目骨架。如果你不記得這些內容,就回到《習題 46》重新複習一遍。

安裝 lpthw.web

在創建你的第一個網頁應用程序之前,你需要安裝一個“Web 框架”,它的名字叫 lpthw.web 。

所謂的“框架”通常是指“讓某件事情做起來更容易的軟件包”。在網頁應用的世界裡,人們創建了各種各樣的“網頁框架”,用來解決他們在創建網站時碰到的問題,然後把這些解決方案用軟件包的方式發佈出來,這樣你就可以利用它們引導創建你自己的項目了。

可選的框架類型有很多很多,不過在這裡我們將使用 lpthw.web 框架。你可以先學會它,等到差不多的時候再去接觸其它的框架,不過 lpthw.web 本身挺不錯的,所以就算你一直使用也沒關係。

使用 pip 安裝 lpthw.web :

$ sudo pip install lpthw.web

[sudo] password for zedshaw:

Downloading/unpacking lpthw.web

Running setup.py egg_info for package lpthw.web

Installing collected packages: lpthw.web

Running setup.py install for lpthw.web

Successfully installed lpthw.web

Cleaning up...

以上是 Linux 和 Mac OSX 系統下的安裝命令,如果你使用的是 Windows,那你只要把 sudo 去掉就可以了。如果你無法正常安裝,請回到《習題 46》,確認自己學會了裡邊的內容。

Warning:其他 Python 程序員會警告你說 lpthw.web 只是另外一個叫做 web.py 的 Web框架的代碼分支(fork),而 web.py 又包含了太多的“魔法(magic)”在裡邊。如果他們這麼說的話,你告訴他們 Google App Engine 最早用的就是 web.py ,但沒有一個 Python 程序員抱怨過它裡邊包含了太多的魔法,因為 Google 用它也沒啥問題。如果Google覺得它可以,那它對你來說也不會差。所以還是回去繼續學習吧,他們這些說法與其說是教導你,不如說是拿他們自己的教條束縛你,你還是忽略這些說法好了。

寫一個簡單的“Hello World”項目

現在我們使用 lpthw.web 做一個非常簡單的“Hello World”項目出來,首先你要創建一個項目目錄:

$ cd projects

$ mkdir gothonweb

$ cd gothonweb

$ mkdir bin gothonweb tests docs templates

$ touch gothonweb/__init__.py

$ touch tests/__init__.py

你最終的目的是把《習題43》中的遊戲做成一個web應用,所以你的項目名稱叫做 gothonweb ,不過在此之前,你需要創建一個最基本的 lpthw.web 應用,將下面的代碼放到 bin/app.py 中:

import web

urls = (

'/', 'index'

)

app = web.application(urls, globals())

class index:

def GET(self):

greeting = "Hello World"

return greeting

if __name__ == "__main__":

app.run()

然後使用下面的方法來運行這個 web 程序:

$ python bin/app.py

http://0.0.0.0:8080/

如果你這樣做:

$ cd bin/ # WRONG! WRONG! WRONG!

$ python app.py # WRONG! WRONG! WRONG!

那麼你就錯了。在所有Python項目中,都不會用 cd 到下一級目錄中去啟動服務,你就在最頂層的目錄啟動服務,這樣所有的系統可以訪問所有的模塊和文件。 去重讀習題46並理解項目佈局和如何使用它。

最後,使用你的網頁瀏覽器,打開 URL http://localhost:8080/ ,你應該看到兩樣東西,首先是瀏覽器裡顯示了 Hello, world! ,然後是你的命令行終端顯示瞭如下的輸出:

$ python bin/app.py

http://0.0.0.0:8080/

127.0.0.1:59542 - - [13/Jun/2011 11:44:43] "HTTP/1.1 GET /" - 200 OK

127.0.0.1:59542 - - [13/Jun/2011 11:44:43] "HTTP/1.1 GET /favicon.ico" - 404 Not Found

這些是 lpthw.web 打印出的 log 信息,從這些信息你可以看出服務器有在運行,而且能瞭解到程序在瀏覽器背後做了些什麼事情。這些信息還有助於你發現程序的問題。例如在最後一行它告訴你瀏覽器試圖獲取 /favicon.ico ,但是這個文件並不存在,因此它返回的狀態碼是404 Not Found 。

到這裡,我還沒有講到任何 web 相關的工作原理,因為首先你需要完成準備工作,以便後面的學習能順利進行,接下來的兩節習題中會有詳細的解釋。我會要求你用各種方法把你的lpthw.web 應用程序弄壞,然後再將其重新構建起來:這樣做的目的是讓你明白運行lpthw.web 程序需要準備好哪些東西.

發生了什麼?

在瀏覽器訪問到你的網頁應用程序時,發生了下面一些事情:

1. 瀏覽器通過網絡連接到你自己的電腦,它的名字叫做 localhost ,這是一個標準稱謂,表示的誰就是網絡中你自己的這臺計算機,不管它實際名字是什麼,你都可以

使用localhost 來訪問。它使用到的網絡端口是8080。

2. 連接成功以後,瀏覽器對 bin/app.py 這個應用程序發出了 HTTP 請求(request),要求訪問 URL / ,這通常是一個網站的第一個 URL。

3. 在 bin/app.py 裡,我們有一個列表,裡邊包含了 URL 和類的匹配關係。我們這裡只定義了一組匹配,那就是 '/', 'index' 的匹配。它的含義是:如果有人使用瀏

覽器訪問 / 這一級目錄, lpthw.web 將找到並加載 class index ,從而用它處理這個瀏覽器請求。

4. 現在 lpthw.web 找到了 class index ,然後針對這個類的一個實例調用了index.GET 這個方法函數。該函數運行後返回了一個字符串,以供 lpthw.web 將其

傳遞給瀏覽器。

5. 最後 lpthw.web 完成了對於瀏覽器請求的處理,將響應(response)回傳給瀏覽器,於是你就看到了現在的頁面。

確定你真的弄懂了這些,你需要畫一個流程圖,來理清信息是如何從瀏覽器傳遞到 lpthw.web ,再到 index.GET ,再回到你的瀏覽器的。

修正錯誤

第一步,把第 11 行的 greeting 變量賦值刪掉,然後刷新瀏覽器。你應該會看到一個錯誤頁面,你可以通過這一頁豐富的錯誤信息看出你的程序崩潰的原因是什麼。當然你已經知道出錯的原因是 greeting 的賦值丟失了,不過 lpthw.web 還是會給你一個挺好的錯誤頁面,讓你能找到出錯的具體位置。試試在這個錯誤頁面上做以下操作:

1. 檢查每一段 Local vars 輸出(用鼠標點擊它們),追蹤裡邊提到的變量名稱,以及它們是在哪些代碼文件中用到的。

2. 閱讀 Request Information 一節,看看裡邊哪些知識是你已經熟悉了的。Request 是瀏覽器發給你的 gothonweb 應用程序的信息。這些知識對於日常網頁瀏覽沒有什麼用處,但現在你要學會這些東西,以便寫出 web 應用程序來。3.試著把這個小程序的別的位置改錯,探索一下會發生什麼事情。 lpthw.web 的會把一些錯誤信息和堆棧跟蹤(stack trace)信息顯示在命令行終端,所以別忘了檢查命令行終端的信息輸出。

創建基本的模板文件

你已經試過用各種方法把這個 lpthw.web 程序改錯,不過你有沒有注意到“Hello World”不是一個好 HTML 網頁呢?這是一個 web 應用,所以需要一個合適的 HTML 響應頁面才對。為了達到這個目的,下一步你要做的是將“Hello World”以較大的綠色字體顯示出來。

第一步是創建一個 templates/index.html 文件,內容如下:

$def with (greeting)

Gothons Of Planet Percal #25

$if greeting:

I just wanted to say $greeting.

$else:

Hello, world!

如果你學過 HTML 的話,這些內容你看上去應該很熟悉。如果你沒學過 HTML,那你應該去研究一下,試著用 HTML 寫幾個網頁,從而知道它的工作原理。不過我們這裡的 HTML 文件其實是一個“模板(template)”,如果你向模板提供一些參數, lpthw.web 就會在模板中找到對應的位置,將參數的內容填充到模板中。例如每一個出現 $greeting 的位置, $greeting 的內容都會被替換成對應這個變量名的參數。

為了讓你的 bin/app.py 處理模板,你需要寫一寫代碼,告訴 lpthw.web 到哪裡去找到模板進行加載,以及如何渲染(render)這個模板,按下面的方式修改你的 app.py:

import web

urls = (

'/', 'Index'

)

app = web.application(urls, globals())

render = web.template.render('templates/')

class Index(object):

def GET(self):

greeting = "Hello World"

return render.index(greeting = greeting)

if __name__ == "__main__":

app.run()

特別注意一下 render 這個新變量名,注意我修改了 index.GET 的最後一行,讓它返回了 render.index() ,並且將 greeting 變量作為參數傳遞給了這個函數。

改好上面的代碼後,刷新一下瀏覽器中的網頁,你應該會看到一條和之前不同的綠色信息輸出。你還可以在瀏覽器中通過“查看源文件(View Source)”看到模板被渲染成了標準有效的HTML 源代碼。

這麼講也許有些太快了,我來詳細解釋一下模板的工作原理吧:

1. 在 bin/app.py 裡面你添加了一個叫做 render 的新變量,它本身是一個web.template.render 對象。

2. 你將 templates/ 作為參數傳遞給了這個對象,這樣就讓 render 知道了從哪裡去加載模板文件。

3. 在你後面的代碼中,當瀏覽器一如既往地觸發了 index.GET 以後,它沒有再返回簡單的 greeting 字符串,取而代之的是你調用了 render.index ,而且將問候語句作

為一個變量傳遞給它。

4. 這個 render_template 函數可以說是一個“魔法函數”,它看到了你需要的是 index.html ,於是就跑到 templates/ 目錄下,找到名字為 index.html 的文件,

然後就把它渲染(render)一遍(叫“轉換一遍”也可以)。

5. 在 templates/index.html 文件中,你可以看到初始定義一行中說這個模板需要使用一個叫 greeting 的參數,這和函數定義中的格式差不多。另外和 Python 語法一

樣,模板文件是縮進敏感的,所以要確認自己弄對了縮進。

6. 最後,你讓 templates/index.html 去檢查 greeting 這個變量,如果這個變量存在的話,就打印出變量的內容,如果不存在的話,就會打印出一個默認的問候信息。

要深入理解這個過程,你可以修改 greeting 變量以及 HTML 模板的內容,看看會有什麼效果。然後創建一個叫做 templates/foo.html 的模板,並且使用一個新的 render.foo() 去渲染它。從這個過程你也可以看出, render 調用的函數名稱只要跟 templates/ 下的 .html 文件名匹配到,這個 HTML 模板就可以被渲染到了。

附加題

1. 閱讀 http://webpy.org/ 裡邊的文檔,它其實和 lpthw.web 是同一個項目。

2. 實驗一下你在上述網站看到的所有的東西,包括裡邊的代碼示例。

3. 閱讀以下 HTML5 和 CSS3 相關的東西,自己練習著寫幾個 .html 和 .css 文件 。

4. 如果你有一個懂 Django 朋友可以幫你的話,你可以試著使用 Django 完成一下習題50、51、52,看看結果會是什麼樣子的。

常見問題

Q: 我好想無法連接到 http://localhost:8080/

那麼試試訪問 http://127.0.0.1:8080/

Q: lpthw.web 和 web.py 有什麼區別?

沒有區別。我只是在特定版本“鎖定” web.py ,以使它對所有學生都是一樣的,然後再命名為 lpthw.web ,上一個版本的 web.py 可能就不同於這一版本。

Q: 我的代碼找不到 index.html (或者其他文件)

你可能是先執行了 cd bin/ ,不要執行這一句,所有的命令都應該在 bin/ 的上一級目錄執行,所以如果你不能執行 python bin/app.py ,說明你在錯誤的目錄上。

Q: 當我們調用模板的時候,為什麼要執行 greeting=greeting 賦值操作

你並沒有給 greeting 賦值,你只是給模板設定一個命名參數。這是聲明的一種,但它隻影響調用模板的功能。

Q: 我的電腦上不能使用8080端口

你可能有一個殺毒程序佔用了這個端口,試試別的端口。

Q: 安裝 lpthw.web 時,我遇到報錯信

息 ImportError "No module named web"你可能安裝了多個版本的Python並且正在使用一個錯誤的版本,或者你是因為使用了一箇舊版本的 pip ,導致安裝沒有成功,試著先卸載 lpthw.web ,在重裝一次,如果還沒有解決問題,再次確認下你是否使用了正確的Python版本。


分享到:


相關文章: