一直以來,Python 都在數據科學領域佔有領導地位,然而隨著要處理的數據量與日俱增,Python 的缺點就顯而易見了,就是處理速度慢、並行處理有所侷限、和缺乏型別安全性的問題,這些對大型 App 來說都是障礙。
很明顯地,Google 已經把 Swift 視為深度學習的未來,為 Tensorflow 在 Swift 上投資了重本。
不過,Python 擁有大量的資源庫,要逐漸擺脫它並不簡單,但是我們仍然可以利用它與 Swift 的互通性。
沒錯,你可以使用 PythonKit 框架從 Swift 運行 Python 程式碼,PythonKit 是 Swift for TensorFlow 項目中基於 Python
模塊的一個框架。
請注意,Python 在 iOS 上不可用,但你還是可以為 macOS 和 Linux 構建非常棒的工具 App。
PythonKit 的優點
- 你的 Swift 程式碼可以直接存取豐富的 Python 模組和 Package。
- Python 開發者可以輕鬆構建 macOS App,以運行自動化腳本 (script),並執行數值計算。
- 你無需在 Swift 中加入巨大的 OpenCV 和 Tensorflow 框架,只要在系統上安裝 Python 副本 (counterparts),就可以在任何需要的 macOS App 中使用它。
在接下來的章節,我們會看看如何在一個 SwiftUI macOS App 中,設置 PythonKit 並執行一些有趣的任務。
在 macOS App 中加入 PythonKit
首先,讓我們建立一個新的 Xcode 專案,以 macOS 為目標,並使用 Swift Package Manager 加入以下的 Package dependancy:
.package(url: "https://github.com/pvieito/PythonKit.git", .branch("master")),
操作步驟為:File -> Swift Packages -> Add Package Dependency -> 輸入這個 git 網址
現在,你可以在 Swift視圖中輸入 import PythonKit
,接著要確認現在使用的 Python 版本,並如此更新版本:
print(Python.version)PythonLibrary.useVersion(2)
//or
PythonLibrary.useVersion(3, 8)
備註:PythonLibrary.useVersion
需要放於 import 的程式碼下面,因為你不可以在 Run-Time 時動態地修改 Python 版本。
接下來,請確保你已從 Signing and Capabilities section 移除了 App 沙盒,因為我們會在 mac 上直接使用 Python。
初次在 Swift 執行 Python 腳本
讓我們以 Python 函式在 .py
檔內寫 hello world。
def hello():
return "Hello Swift, I'm Python"
然後存檔,並記住所存的路徑。
以下的 Swift 方法會呼叫上面的函式,並回傳結果:
func runPythonCode(){
let sys = Python.import("sys")
sys.path.append(dirPath)
let example = Python.import("sample")
let response = example.hello()
}
從以上的 Swift 程式碼中,我們注意到幾項事情:
dirPath
是檔案位置的路徑,我的檔案位置路徑是:/Users/anupamchugh/Desktop/workspace/
。Python.import
是用來匯入 Python 模組的,以我們的範例來說,我們將匯入sample.py
檔案,當中包含了我們的 hello world 程式碼。example
是一個 PythonObject 型別的 Swift 實例,我們將在這裡呼叫hello
函式。- 回應實例也是一個
PythonObject
,能在範例中隱性地轉換成字串。
我們可以依下列做法,將 PythonObject 轉換成原生 Swift 的型別:
let str = String(pythonString)!
let arr = Array(pythonArray)!
轉換 Python 變數並回傳至 Swift
讓我們來看看一個典型範例,試著在 Swift 的 Python 函式中,轉換兩個變數的內容值:
def swap(a, b):
a, b = b, a
return a, b
現在,從 Swift 函式呼叫它,並取得結果:
func swapNumbersInPython(){
let sys = Python.import("sys")
sys.path.append(dirPath)
let example = Python.import("sample")
let response = example.swap(swapA, swapB)
let arr : [Int] = Array(response)!
swapA = arr[0]
swapB = arr[1]
}
swapA
和 swapB
都是 SwiftUI 的狀態變數,它們會在螢幕上被更新。
現在,讓我們利用以上的 Python 腳本執行 macOS SwiftUI App:
如此一來,我們就成功建置了第一個可以將 Swift 與 Python 互通的 macOS App。
但這樣還不夠。讓我們來撰寫一個更棒的 Python 腳本。
使用 Python 腳本下載影片 並顯示於 SwiftUI VideoPlayer
Python 有個非常受歡迎的 Package,叫做 youtube-dl
,用來從 Youtube 或其他網站下載影片。
讓我們先將它下載到 mac,並以 Python3 執行下列的 pip 指令動作:
pip3 install youtube-dl
接著,在 Python 檔案內加入下列函式:
備註:你可以在Github 擷取程式碼。
link
和 path
參數都是從 Swift 傳遞過來的,前者是影片連結,而後者是將影片保存的目錄路徑。
ydl.download()
會下載影片,然後我們會把 videoName
回傳到 Swift 程式碼:
func downloadVideo(link: String){
let sys = Python.import("sys")
sys.path.append(dirPath)
let example = Python.import("sample") let response = example.downloadVideo(link, dirPath)
videoPath = String(response)
}
在 WWDC2020 中,SwiftUI 在 macOS 11.0 和 iOS 14 的裝置上,新增了 VideoPlayer
的內建支援。即使是 iOS 13 的裝置,你也可以利用 UIViewRepresentable
協定,來建立一個客製的影片視圖。
我們可以使用 videoPath
,如此在 SwiftUI 顯示所下載的影片檔案:
let url = URL(fileURLWithPath:dirPath+videoPath)
VideoPlayer(player: AVPlayer(url: url))
讓我們運行以上的 mac App 來看看結果:
影片是一段 Batman 的預告片。
你可以在 GitHub 儲存庫 上找到 SwiftUI App 的完整程式碼與 Python 腳本。
總結
在本篇教學中,我們看到 Python、Swift 的互通性,並我們可以在 Swift 執行 Python 程式碼。除了影片下載器外,你還可以運行自動化任務,例如批次文件重新命名、硬碟空間分析功能等。
Python 和 Swift 是兩種語法簡潔的語言,儘管後者是深度學習的未來,但前者在未來幾年都會繼續扮演副手的重要角色。
聯絡方式:電郵 [email protected]