天天看點

eval() python_Boa: 在 Node.js 中使用 Python

eval() python_Boa: 在 Node.js 中使用 Python

作者 | Yorkie 這次主要給 大家帶來一個好東西,它的主要用途就是能讓大家在 Node.js 中使用 Python 的接口和函數。 可能你看到這裡會好奇,會疑惑,會不解,我 Node.js 大法那麼好,幹嘛要用 Python 呢? 如果你之前嘗試了解過一些機器學習的 JavaScript 的應用,就會比較清楚這背後的原因。

現狀是機器學習生态幾乎是捆綁在 Python 這門語言在高速疊代着的,而 JavaScript 隻能望其項背,如果我們期望從零做到 Python 如今的規模,需要付出的工作量是巨大的,這個我在幾年前寫了 tensorflow-nodejs 的時候,就已經這麼覺得了。

是以,我們就必須換一個思路,既然無法超越你,那麼就利用你。對于腳本語言的開發者來說,其實并不在意底層是如何實作的,隻要上層的語言和接口是我熟悉的就好,是以 Boa 就是為此而誕生的一個 Node.js 庫,它通過橋接 CPython 來讓 JavaScript 具備通路 Python 生态的能力,另外又借助于 ES6 新特性,來為使用者提供無縫的開發體驗,那麼到底是如何的體驗呢?

下面來看一個簡單的例子:

是不是很簡單呢,隻需要通過 boa.import 将 Python 的對象加載進來後,剩下的對象通路、函數調用以及數組通路都與我們使用 JavaScript 毫無差別。

上面的例子除了示例了如何從 JavaScript 中繼承自一個 Python 的類之外,還展示了我們如何使用 PyTorch 來建立一個模型,這是不是很 JavaScript 呢?

值得一提的是,在 Boa 的代碼中,沒有對 PyTorch 做過任何的封裝,隻要你在本地通過 Python 安裝了對應的包就可以像上面的代碼一樣使用了,是以理論上你可以對任何 Python 包做上面所做的事情。

接下來,我們分别介紹一些主要的方法。

builtins()

Python 會内置一些常用的方法在 builtin 中,具體的 API 清單在:https://docs.python.org/3.7/library/functions.html,那麼 Boa 也提供了對應的方法:

import(name)

除了内置的方法外,最重要的功能便是加載 Python 包,那麼 import 就是做這個事兒的。

kwargs(map)

接下來是 Python 中的關鍵字參數(Keyword Arguments),在 Python 中,提供了一種使用 Map 的方式來表示參數,如:

它能更好地幫助調用者了解每個參數的含義,為此,在 Boa 中增加了 kwargs 方法來支援這種用法:

with(ctx, fn)

With 可能對于一些熟悉 JavaScript 曆史的人會比較眼熟,但 Python 中的 with,用法和目的并不與 JavaScript 相同,Python 中的 with 語句有點類似于 JavaScript 中的 Block Scoping:

上面的 Python 代碼是将 localcontext() 的狀态儲存下來,然後開始執行 with 語句中的塊代碼,最後,将 localcontext() 的狀态釋放。

内部的實作機制就是每個傳到 with 語句中的變量需要實作兩個方法:enter 和 exit,然後分别在塊代碼執行前後調用,是以對于 Boa 中的用法,如下:

上面的例子是 PyTorch 中一個普通的計算模型效果的邏輯,首先通過 torch.no_grad() 設定了一個上下文,然後開始執行計算的代碼,在塊代碼執行結束後,會自動将狀态恢複。

eval(str)

最後一個要說的,就是動态的執行一些 Python 表達式(單行),為什麼要提供這麼一個方法呢?這還是要說回 Python 的優勢,在一些很複雜的資料處理的場景,往往 Python 表達式還是能非常簡單易懂地表達,這樣就大大地減少了代碼的複雜度,我們先來看一個例子:

上面的代碼如果要換成 JavaScript 的話:

看着似乎差不多了多少是吧?那麼再來看看下面的例子:

怎麼樣,是否是感覺上面的例子已經沒法使用 JavaScript 簡單的一行就能搞定了呢?

不過值得一提的是,JavaScript 在這方面也在漸漸地彌補,這裡 是整理的一些 TC39 正在做的一些相關的标準,其中就包括上面的 Slice Notation。

說回到 eval 的定位,它像是對 JavaScript 的補充,它在一些标準還未落地和穩定之前,可以讓我們使用 Python 表達式來更簡單地表達,而所需要的僅僅是一些低成本的學習即可。

接下來就說說 eval 到底如何使用,它接受一個“字元串”,但我們一般在使用時都會通過 Template String,下來先看兩個例子:

看完上面兩行代碼,它們是比較少見的用法。真正常用,也是最能發揮出 eval 效果的是使用 Tagged Template String,這種用法就像我們一開始看到的一樣,在 eval 後面直接跟模版字元串的内容,這樣做的好處是 eval 函數會接收到所有的模版參數,這樣我們便可以将 JavaScript 的對象和 Python 表達式打通,實作更平滑的使用體驗,如下:

上面就是把 chunk 傳到了表達式中,再通過 Python 的 Slice Notation 文法去取到對應的值,最後傳回到 JavaScript 的世界中。

尾聲

好了,簡單的 API 介紹就先到這裡,如果想了解更多 API 和 Boa 的能力,可以到 Boa 的文檔了解:https://github.com/alibaba/pipcook/blob/master/docs/tutorials/want-to-use-python.md。

另外,Boa 作為 Pipcook 的一個子項目,也非常歡迎大家來加入進來,對于想加入的同學可以通過這些 Issue 作為不錯的開始:https://github.com/alibaba/pipcook

最後再說一下 Boa 的初衷,就是希望能讓 Node.js 開發者更無縫地使用 Python 中豐富的機器學習生态。可以說,從今天開始,你就可以開始看着 Python 的文檔,使用 JavaScript 來“學習”機器學習和深度學習了!

eval() python_Boa: 在 Node.js 中使用 Python

敬請關注「Nodejs技術棧」微信公衆号,擷取優質文章

▼往期精彩回顧▼Nodejs Stream pipe 的使用與實作原理分析Nodejs 中基于 Stream 的多檔案合并實作Node.js util.promisify 實作源碼解析深入 Nodejs 源碼探究 CPU 資訊的擷取與使用率計算Nodejs 進階:解答 Cluster 子產品的幾個疑問多元度分析 Express、Koa 之間的差別Node.js 服務 Docker 容器化應用實踐JavaScript 浮點數之迷:大數危機 Node.js 是什麼?我為什麼選擇它?TypeScript 面向對象程式設計(OOP)不容錯過的 Node.js 項目架構Node.js 記憶體管理和 V8 垃圾回收機制

eval() python_Boa: 在 Node.js 中使用 Python

繼續閱讀