2019年9月7日 星期六

Brython 學習筆記 (一) : 環境配置與 Hello 測試

Brython (Browser Python) 是一個用 Python 3 撰寫的框架, 它實作了 DOM 元素與事件, 用來取代瀏覽器中的草稿語言 Javascript. 事實上 W3C 的 DOM 規格本身與語言無關 (language-neutral), 可用任何程式語言存取與操控, Brython 支援全部 DOM 物件以及其屬性與方法, 與 Javascript 一樣可存取與操控網頁元素  :

"Brython (Browser Python) is an implementation of Python 3 running in the browser, with an interface to the DOM elements and events. Brython is designed to replace Javascript as the scripting language for the Web. "

Tsung's Blog 在 2013 年寫過一篇文章介紹 Brython, 但作者當時認為沒有實用性, 因此只是簡單摘要介紹, 參考 :

Brython - 在瀏覽器用 Python 取代 JavaScript

但時隔 6 年 Brython 仍持續活躍發展, 說不定哪天就被 Chrome 放進去成為 Javascript 外的第二種前端 Scripting 選項.

Brython 官網相關連結如下 :

http://brython.info/index.html (首頁)
http://brython.info/static_doc/en/intro.html?lang=en (教學文件)
https://github.com/brython-dev/brython/releases (下載)
https://github.com/brython-dev/brython (GitHub)
http://brython.info/demo.html?lang=en (展示教學)
How Brython works (語法簡介)
http://brython.info/tests/editor.html (Python 測試編輯器)


在本機中使用 Brython 需先配置環境, 首先在官網按 Download 到 Github 下載 Brython 的 zip 壓縮檔 (目前是 v3.7.4 版), 解壓縮後得到兩個 js 檔, 其中 brython.js 約  670KB, 是 Brython 的實作 DOM 物件之主體, 而 brython_stdlib.js 則支援 Python 標準函式庫, 如果需要用到 Python 標準函式庫則需另外載入此檔案.




將 brython.js 放在專案資料夾的 js 子目錄下, 利用下面模板網頁載入 brython.js 即可開始使用 Python 操控瀏覽器的元素了. 網頁中使用 Brython 的程序如下 :
  1. 使用 script 元素載入 brython.js
  2. 在 body 元素中以 onload 呼叫 brython() <body onload=brython()> 
  3. 在 script 元素中撰寫 Python 程式碼或用 src 載入外部 Python 檔案. 

Bython 的 HTML 模板 (local)

<!DOCTYPE html>
<html>
<head>
  <title>Brython 測試</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1">
</head>
<script src="js/brython.js"></script>
<body onload="brython()">
  <script type="text/python">
    //Python codes are here
  </script>
</body>
</html>


在 body 元素中須以 onload 屬性呼叫 brython() 建構子以建立 Python 執行環境. 操控網頁的 Python 程式碼則放在 body 內的 script 元素內容裡, 也可以將 Python 程式檔以 src 屬性載入, 但注意 type 屬性必須是 "text/python" 才行.


Brython 的 HTML 模板 (CDN) : 外部 Python 檔

<!DOCTYPE html>
<html>
<head>
  <title>Brython 測試</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1">
</head>
<script src="js/brython.js"></script>
<body onload="brython()">
  <script type="text/python" src="mypython.py"></script>
</body>
</html>


另外一個方法是直接使用 CDN 來源所提供的 Brython 檔案, 例如 cdnjs.com, 只要在 script 標籤的 src 屬性中指定 Brython CDN 檔的 URL 即可, 而且它有提供壓縮過的檔案, 只有約 545 KB, 不僅體積少了 130 KB, 而且不需要自己配置環境 :


<script src="https://cdnjs.cloudflare.com/ajax/libs/brython/3.7.4/brython.min.js">
</script>

網頁模板如下 : 

Brython 的 HTML 模板 (CDN)

<!DOCTYPE html>
<html>
<head>
  <title>Brython 測試</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1">
</head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/brython/3.7.4/brython.min.js"></script>
<body onload="brython()">
  <script type="text/python">
    //Python codes are here
  </script>
</body>
</html>


Brython 實作了 DOM API 的存取介面, 頂層是代表 Javascript 的 javascript 模組與代表瀏覽器的 browser 模組, browser 底定義了 document, window, ajax, javascript 等物件以及 html 子模組 (底下定義全部大寫 HTML 元素之物件) 等等.



<!DOCTYPE html>
<html>
<head>
  <title>Brython 測試</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1">
</head>
<script src="js/brython.js" async></script>
<button id="say_hello">說哈囉</button>
<body onload="brython()">
  <script type="text/python">
    from browser import document, alert     
    def hello(str):
        alert("Hello World!")
    document["say_hello"].bind("click", hello)
  </script>
</body>
</html>




此例中先從 browser 模組匯入 document 物件與 alert() 函數, document 透過 id 存取網頁元素之 DOM 物件, 呼叫 bind() 綁定 click 事件至處理函數hello() . 

將上面範例 1 改為從文字欄位擷取名字用 alert() 顯示 "Hello Somebody!" :


<!DOCTYPE html>
<html>
<head>
  <title>Brython 測試</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1">
</head>
<script src="js/brython.js" async></script>
<input id="name" autocomplete="off">
<button id="say_hello">說哈囉</button>
<body onload="brython()">
  <script type="text/python">
    from browser import document, alert
    def hello(str):
        alert("Hello " + document["name"].value + "!")
    document["say_hello"].bind("click", hello)
  </script>
</body>
</html>




此例添加了一個 id=name 的文字欄位來填入名字, 在 hello() 中用 document['name'].value 即可取得文字欄位之值, 用來串接在 "Hello " 後面.

4 則留言 :

David Wang 提到...

剛剛試了一下, 感覺brython這個方式真的很棒!
python真的有可能會被標準化到瀏覽器內。

小狐狸事務所 提到...

這樣就可以只學 Python 一種語言而到處可用了!

Unknown 提到...

雖說是 Python 語言, 却沒有了 Python 的很多長處啊!

我希望能讀到os.environ['USERNAME'], 有什麼辦法嗎?

小狐狸事務所 提到...

應該不行, 它只是用來取代 Javascript 而已, 在瀏覽器裡連 Javascript 也沒辦法取得系統資訊, 要 Node.js 才可以.