
Python 入門指南 5.0
單元 42 - 啟動伺服器與加入 encrypt.py

Python 啟動內建伺服器 (server) 的指令如下
以下在 Mac 示範啟動 Python 內建伺服器,先把所有範例檔案 index.html 、 app_style.css 、 encrypt.py 及 controller.py 都放到資料夾 html5_dmeo 中,然後命令列切換路徑到 html5_dmeo ,於該路徑打啟動 Python 內建伺服器的指令,如下圖

範例完整檔案請參考 index.html 、 app_style.css 、 encrypt.py 及 controller.py 。
這裡連結到網頁的網址為 http://localhost:8000/ ,注意不是 https ,用 Google Chrome 開啟如下圖

啟動伺服器後,預設首頁就是 index.html ,因此網址後不需要再添加檔名。
冒號後的 8000 是埠號,注意這裡必須連用 8000 的埠號,不然會連線失敗。
然後回到命令列來看,新增 5 行資訊,包括成功讀取 CSS 及 Python 檔案

如果外連失敗,在命令列這裡會提供相關資訊。
打開 Google Chrome 的開發人員工具,可以看到會直接在 Console 顯示 encrypt.py 中的執行結果,也就是說,如果我們在程式中使用 print() 函數 (function) ,結果會顯示在開發人員工具的 Console 這裡

接下來看到 index.html ,引入 CSS 檔案與 Brython 程式庫之後,第 17 行引入我們在「軟體開發篇」發展的 encrypt.py ,這讓 index.html 可以使用 Encrypt 類別 (class)
17 18 | <script type="text/python" src="encrypt.py"> </script> |
然後在第 12 行再引入控制程式 controller.py
20 21 | <script type="text/python" src="controller.py"> |
下面編密碼小工具的視窗元件放在 <table> 中
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | <div class="app"> <table class="app"> <tr><td>輸入:</td> <td class="input" colspan="6"><input type="text" id="input" name="input" autofocus></td></tr> <tr><td>輸出:</td> <td class="output" colspan="6"><input type="text" id="output" name="output" readonly></td></tr> <tr><td><button id="new" type="button">新建</button></td> <td><button id="load" type="button">載入</button></td> <td><button id="save" type="button">存檔</button></td> <td><button id="encode" type="button">編碼</button></td> <td><button id="decode" type="button">解碼</button></td> <td><button id="clear" type="button">清除</button></td> <td><button id="copy" type="button">拷貝</button></td></tr> <tr><td id="result" colspan="7">狀態列</td></tr> </table> </div> |
先注意到第 31 行的 <input> 有 autofocus
31 | <td class="input" colspan="6"><input type="text" id="input" name="input" autofocus></td></tr> |
autofocus 會讓瀏覽器 (browser) 開啟 index.html 自動聚焦在這個文字輸入方塊,但是使用者一旦點擊其他部分,就不會再聚焦在這裡,因此我們在後續 Python 程式還要外設定,讓網頁焦點始終保持於此。
下面第 33 的 <input> 有 readonly
33 | <td class="output" colspan="6"><input type="text" id="output" name="output" readonly></td></tr> |
readonly 讓這個文字方塊變成唯讀,因此使的者無法在這個文字方塊輸入內容。
下一行則是七個按鈕,最後一行則是顯示結果的狀態列,注意到 colspan 屬性 (attribute) ,這可以設定單一 <td> 擴展幾個 <td> ,量是輸入、輸出的 <td> 都擴展 6 個,狀態列則是擴展 7 個。
繼續切換到 controller.py ,第 6 行引入 Encrypt 類別
6 | from encrypt import Encrypt |
第 8 行到第 12 行則是定義作為常數的全域變數 (global variable)
8 10 12 | e = None userinput = "" result = "" |
以上的全域變數在 Tk 應用程式中是定義為 EncryptController 的屬性,這裡由於是採取設計函數,所以用全域變數比較方便,如果是大型網頁應用程式則可能會依需求採取其他的設計方式。
然後第 14 行,這裡輸入方字方塊的元素 (element) 物件 (object) 呼叫 focus() 方法 (method)
14 | doc["input"].focus() |
下面在每個函數結尾都會呼叫輸入方字方塊元素物件的 focus() 方法,讓使用者焦點一直保持輸入方字方塊上。
繼續看到跟新建按鈕連結的 new_function()
17 19 21 23 25 | def new_function(event): global e e = Encrypt() doc["result"].innerHTML = str(e) doc["input"].focus() |
new_function() 中是先用 global 宣告全域變數,然後建立新 Encrypt 型態的全域變數 e ,接下來就在狀態列顯示密碼表。
其實以上可以發現跟單元 34 介紹 EncryptController 的 new_method() 很像,因為我們是做相同功能的移植,然後依情況調整程式碼。
然後 encode_function() 進行編碼,流程一樣是先檢測使用者是否有輸入,接下來檢查是否有編碼物件,兩者都成立才進行編碼
60 62 64 66 68 69 71 73 74 76 78 80 82 | def encode_function(event): global e, userinput, result userinput = doc["input"].value if userinput == "": doc["result"].innerHTML = "沒有輸入文字唷!" else: if e == None: doc["result"].innerHTML = "出錯了唷!無法編碼" else: result = e.toEncode(userinput) doc["output"].value = result doc["result"].innerHTML = "編碼結果如上" doc["input"].focus() |
文字輸入方塊可以用 value 屬性取值或設定值,至於 decode_function() 幾乎一樣。下面我們來實際執行看看吧!先點擊新建按鈕,底下狀態列計會出現密碼表

注意命令列伺服器這裡也新增一行執行成功的訊息

然後輸入英文句子,點擊編碼,編碼結果就出現在輸出欄位

解碼也沒問題

編碼、解碼幾乎跟 Tk 視窗應用程式一樣,倒是存檔會比較特殊,因為網頁為了安全性,瀏覽器並不允許直接存檔到電腦中,所以下個單元我們要討論瀏覽器怎麼做存檔工作。
中英文術語對照 | |
---|---|
瀏覽器 | browser |
類別 | class |
元素 | element |
函數 | function |
全域變數 | global variable |
方法 | method |
物件 | object |
伺服器 | server |
重點整理 |
---|
1. 啟動 Python 內建伺服器的指令為 python -m http.server 。 |
2. 瀏覽器的開發人員工具可以即時顯示除錯資訊。 |
3. 在網頁中要使用 Enrypt 類別需要用 <script> 引入 encrypt.py 。 |
4. 設定 <input> 的 autofocus 屬性,可以在網頁開啟後自動聚焦在該元素。 |
5. 設定 <input> 的 readonly 屬性,可以讓該元素變成唯讀狀態。 |
6. 函數間如果需要共通的變數,設定全域變數會比較方便。 |
問題與討論 |
---|
1. 為什麼要使用瀏覽器的開發人員工具?不能簡單使用命令列就好嗎? |
2. 如果不用全域變數,函數間要怎麼樣使用共同的變數? |
練習 |
---|
1. 寫一個 CSS 檔案 exercise4201.css ,替底下練習的 HTML 設計樣式表。 參考樣式碼 |
2. 寫一個 HTML 檔案 exercise4202.html ,套用練習 1 的 CSS 檔案,替底下練習設計目錄網頁。 參考標記碼 |
3. 寫一個 HTML 檔案 exercise4203.html ,套用練習 1 的 CSS 檔案,設計一個顯示歡迎訊息的網頁。 參考標記碼 |
4. 寫一個 HTML 檔案 exercise4204.html ,套用練習 1 的 CSS 檔案,設計一個顯示現在時間的網頁。 參考標記碼 |
5. 寫一個 HTML 檔案 exercise4205.html ,套用練習 1 的 CSS 檔案,設計一個按下按鈕進行倒數計時 10 秒的網頁。 參考標記碼 |
6. 寫一個 HTML 檔案 exercise4206.html ,套用練習 1 的 CSS 檔案,設計一個輸入美金匯率進行換算的網頁。 參考標記碼 |
7. 寫一個 HTML 檔案 exercise4207.html ,套用練習 1 的 CSS 檔案,設計一個計算機的網頁。 參考標記碼 |
8. 寫一個 HTML 檔案 exercise4208.html ,套用練習 1 的 CSS 檔案,設計一個擲骰子遊戲的網頁。 參考標記碼 |
9. 寫一個 HTML 檔案 exercise4209.html ,套用練習 1 的 CSS 檔案,設計一個猜數字遊戲的網頁。 參考標記碼 |
10. 寫一個 HTML 檔案 exercise4210.html ,套用練習 1 的 CSS 檔案,設計一個 4×4 鬥獸棋遊戲的網頁。 參考標記碼 |
