網(wǎng)絡瀏覽器中運行Python腳本PyScript剖析
正文
PyScript可以讓你在瀏覽器中直接運行Python腳本,與JavaScript并排,在你的代碼和網(wǎng)頁之間進行雙向互動。
由Anaconda創(chuàng)建的PyScript是一項實驗性的但很有前途的新技術(shù),它使Python運行時在支持WebAssembly的瀏覽器中作為一種腳本語言使用。
每個現(xiàn)代常用的瀏覽器現(xiàn)在都支持WebAssembly,這是許多語言(如C、C++和Rust)可以編譯的高速運行時標準。Python的參考實現(xiàn)是用C語言編寫的,一個早期項目Pyodide提供了Python運行時的WebAssembly移植。
不過,PyScript的目標是提供一個完整的瀏覽器環(huán)境,將Python作為一種網(wǎng)絡腳本語言運行。它建立在Pyodide之上,但增加或加強了一些功能,如從標準庫中導入模塊、使用第三方導入、配置與文檔對象模型(DOM)的雙向交互,以及做許多其他在Python和JavaScript世界中有用的事情。
現(xiàn)在,PyScript仍然是一個原型和實驗性項目。Anaconda 并不推薦在生產(chǎn)中使用它。但好奇的用戶可以在PyScript網(wǎng)站上嘗試一些例子,并使用可用的組件在瀏覽器中構(gòu)建實驗性的Python+JavaScript應用程序。
在這篇文章中,我們將參觀一下PyScript的基礎知識,看看它是如何讓Python和JavaScript進行交互的。
使用PyScript編程
PyScript的核心是一個單一的JavaScript include,你可以將其添加到網(wǎng)頁中。這個 include 加載了基本的 PyScript 運行時間,并自動添加了對 PyScript 中使用的自定義標簽的支持。
下面是一個PyScript的 "hello, world "項目的簡單例子。
<!DOCTYPE html> <html> <head> <link rel="stylesheet" rel="external nofollow" rel="external nofollow" /> <script defer src="https://pyscript.net/unstable/pyscript.js"></script> </head> <body> <py-script output="out"> print("Hello world") </py-script> <div id="out"></div> </body> </html>
head
文檔中的script
標簽加載了PyScript的核心功能。pyscript.css
樣式表是可選的,但很有用。在其他方面,它在頁面加載時向用戶插入了關(guān)于頁面正在做什么的通知--加載Python運行時,初始化,等等。
Python代碼被包含在自定義的py-script
標簽中。請注意,代碼應該按照Python的縮進慣例進行格式化,否則將無法正常運行。如果你使用的編輯器能自動重新格式化HTML,請注意這一點;它可能會弄亂py-script
塊的內(nèi)容,使其無法運行。
一旦PyScript組件加載完畢,任何Python代碼都會被評估。如果標簽中的腳本寫到stdout
(如print
) 語句中,你可以通過提供一個output
屬性來指示在頁面的什么地方顯示輸出。在這個例子中,腳本的stdout
被引導到ID為"out"
的div
。
如果你把它保存到一個文件中,并在網(wǎng)絡瀏覽器中打開它,你會首先看到一個 "加載 "指示器和一個暫停,因為瀏覽器獲得了PyScript的運行時間并將其設置好。該運行時在未來的加載中應保持緩存,但仍需要一些時間來激活。之后,Hello world
應該出現(xiàn)在頁面上。
標準庫導入
僅僅使用Python的內(nèi)建程序的腳本只有一點用處。Python 的標準庫在 PyScript 中可用,就像你在常規(guī) Python 中使用它一樣:只需import
并開始工作。標準庫的導入在PyScript中應該只是工作。
如果你想修改上面的腳本塊來顯示當前的時間,你不需要用與傳統(tǒng)Python不同的方法。
import datetime print ("Current date and time:", datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S"))
使用來自PyPI的庫
如果我們想從PyPI中安裝一個包并使用它呢?PyScript 有另一個標簽,py-env
,它指定了需要安裝的第三方軟件包。讓我們用這兩個塊來替換原始腳本中的py-script
塊。
<py-env> - humanize </py-env> <py-script output="out"> from datetime import datetime import humanize now_int = int(datetime.timestamp(datetime.now())) now_fmt = humanize.intcomma(now_int) print("It has been", now_fmt, "seconds since the epoch.") </py-script>
py-env
塊讓我們列出要添加的軟件包,就像我們在 Python 項目的requirements.txt
文件中列出它們一樣。然后我們可以像對待其他 Python 軟件包一樣導入和使用它們。在這個例子中,我們使用了一個名為humanize
的第三方軟件包,以使數(shù)字輸出更容易閱讀。
注意,并不是所有來自PyPI的包都能按預期安裝和運行。例如,requests
需要訪問尚不支持的網(wǎng)絡組件。(這個問題的一個可能的解決方法是使用pyodide.http.pyfetch
,它被原生支持)。但是純 Python 包,如humanize
,應該運行良好。Anaconda 提供的例子中使用的包,如numpy
,pandas
,bokeh
, 或matplotlib
,也可以運行。
本地導入
對于另一種常見的情況,假設你想從與你的網(wǎng)頁在同一目錄樹下的其它 Python 腳本中導入。使用導入可以更容易地將更多的 Python 邏輯從網(wǎng)頁本身移出,在那里它和你的演示文稿混在一起,可能會變得難以處理。
通常,Python 使用文件系統(tǒng)中其他.py
文件的存在作為它可以導入的指示。PyScript 不能以這種方式工作,所以你需要指定哪些文件可以作為可導入模塊。
比方說,你有一個名為index.html
的網(wǎng)頁,在你的 web 服務器的某個目錄下,你想在它旁邊放置一個名為main.py
的 Python 文件。這樣,你的頁內(nèi)腳本就可以只是import main
,而你可以把大部分的 Python 邏輯限制在實際的.py
文件中。
在你的py-env
塊中指定你想導入的 Python 文件。
- paths:`` - ./main.py
這將允許main.py
,在與網(wǎng)頁本身相同的 web 服務器目錄下,可以與import main
一起導入。
要記住一件重要的事情。你不能對你在瀏覽器中本地啟動的網(wǎng)頁進行這樣的導入。這是由于WebAssembly運行時和瀏覽器本身對文件系統(tǒng)訪問的限制造成的。相反,你需要在網(wǎng)絡服務器上托管這些網(wǎng)頁,以提供網(wǎng)頁和.py
文件。
[也在InfoWorld上:在2022年編寫現(xiàn)代Python的4個關(guān)鍵]
REPL 標簽
Python用戶應該熟悉Jupyter Notebook,它是Python的瀏覽器內(nèi)實時編碼環(huán)境,通常用于數(shù)學和統(tǒng)計學。PyScript為這樣的環(huán)境提供了一個原始的構(gòu)建模塊,即py-repl
標簽。
py-repl
在網(wǎng)頁上生成一個輸入字段,其功能就像一個非?;镜腏upyter筆記本環(huán)境。下面是一個來自Anaconda自己演示的例子。
<!DOCTYPE html> <html lang="en"> <head> <link rel="stylesheet" rel="external nofollow" rel="external nofollow" /> <script defer src="https://pyscript.net/alpha/pyscript.js"></script> </head> <body> <h1><b>pyscript REPL</b></h1> Tip: press Shift-ENTER to evaluate a cell <div> <py-repl id="my-repl" auto-generate="true"> </py-repl> </div> </body> </html>
運行這段代碼,你會看到一個輸入字段,它的工作原理類似于Python的REPL。
目前,REPL標簽很少有記錄的自定義方式。例如,如果你想以編程方式訪問一個單元格的內(nèi)容或其結(jié)果,沒有明確的文檔說明如何做到這一點。
IDG
PyScript的類似Jupyter的REPL組件可以讓你在頁面中交互式地運行Python,盡管它還不是很靈活或可配置。
與 JavaScript 事件監(jiān)聽器互動
因為 PyScript 是基于pyodide
的,所以它使用pyodide
的機制來與 DOM 交互。例如,如果我們想獲得一個網(wǎng)頁上的輸入框的值并在我們的Python代碼中使用它,我們會這樣做。
<input id="txt"> <py-script> from js import document, console from pyodide import create_proxy def _eventlog(e): console.log(f"Input value: {e.target.value}") eventlog = create_proxy(_eventlog) document.getElementById("txt").addEventListener("input", eventlog) </py-script>
js
庫為許多常見的 JavaScript 實體提供了一個 Python 接口,比如document
和console
對象。它們在PyScript中的行為與在JavaScript中的行為幾乎完全相同。pyodide
中的create_proxy
函數(shù)可以讓我們?nèi)∫粋€ Python 函數(shù)對象并為它生成一個 JavaScript 接口,因此它可以被用作input
框的事件監(jiān)聽器。input
框中的任何按鍵都會被記錄到控制臺,但它們也可以在Python端被處理。
以上就是網(wǎng)絡瀏覽器中運行Python腳本PyScript剖析的詳細內(nèi)容,更多關(guān)于瀏覽器運行Python PyScript的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
pandas中apply和transform方法的性能比較及區(qū)別介紹
這篇文章主要介紹了pandas中apply和transform方法的性能比較,在文中給大家講解了apply() 與transform()的相同點與不同點,需要的朋友可以參考下2018-10-10

Python使用Chrome插件實現(xiàn)爬蟲過程圖解

python 環(huán)境安裝及編輯器配置方法小結(jié)

pytest用例間參數(shù)傳遞的兩種實現(xiàn)方式示例