戰(zhàn)教程)
如何用PyO3讓Python代碼跑在Rust里嵌入Python解釋器的完整實(shí)戰(zhàn)教程【免費(fèi)下載鏈接】pyo3Rust bindings for the Python interpreter項(xiàng)目地址: https://gitcode.com/gh_mirrors/py/pyo3PyO3是 Python 解釋器的 Rust 綁定Rust bindings for the Python interpreter它讓你可以直接在 Rust 程序內(nèi)部嵌入并運(yùn)行 Python 代碼——調(diào)用 Python 函數(shù)、執(zhí)行 Python 腳本、導(dǎo)入 Python 模塊甚至把 Rust 寫好的模塊反向暴露給 Python 使用。本教程帶你從零完成Rust 嵌入 Python 解釋器的完整流程環(huán)境準(zhǔn)備、核心 API 速查、4 種執(zhí)行 Python 代碼的方式以及雙向打通的實(shí)戰(zhàn)技巧。為什么要在 Rust 里嵌入 Python 解釋器大多數(shù)教程教你用 Python 調(diào)用 Rust寫擴(kuò)展模塊但 PyO3 同樣擅長(zhǎng)反方向把 Python 當(dāng)作可嵌入的引擎。典型場(chǎng)景包括高性能宿主 腳本化能力用 Rust 寫核心邏輯用內(nèi)嵌的 Python 提供插件系統(tǒng)、用戶自定義腳本本地執(zhí)行 Python 任務(wù)在 CLI 工具中直接跑 Python 表達(dá)式或數(shù)據(jù)處理邏輯無(wú)需啟動(dòng)子進(jìn)程雙向互調(diào)Rust 調(diào)用 Python 庫(kù)Python 同時(shí)也能 import 你注冊(cè)的 Rust 模塊PyO3 通過(guò)Pythonpy令牌證明當(dāng)前線程已附著到 Python 解釋器這是理解其 API 的核心設(shè)計(jì)詳見官方指南 guide/src/python-from-rust.md。嵌入 Python 的兩種方式快速了解差異PyO3 提供兩條嵌入路徑按需求二選一方式適用場(chǎng)景說(shuō)明Python::attach長(zhǎng)生命周期程序多次進(jìn)入/離開 Python 上下文線程可反復(fù)附著與分離with_embedded_python_interpreter一次性嵌入初始化解釋器 → 執(zhí)行閉包 → 清理資源只能調(diào)用一次完整實(shí)現(xiàn)位于 src/interpreter_lifecycle.rs其中with_embedded_python_interpreter會(huì)自動(dòng)完成Py_InitializeEx初始化、導(dǎo)入threading模塊并關(guān)聯(lián)主線程最后負(fù)責(zé)收尾清理是最省心的全托管方案??焖偕鲜? 步讓 Rust 跑起 Python第 1 步準(zhǔn)備環(huán)境Rust 工具鏈stable最低版本 1.83Python 3.9推薦虛擬環(huán)境構(gòu)建工具如 maturin完整安裝說(shuō)明見 guide/src/getting-started.md。第 2 步創(chuàng)建項(xiàng)目并引入 PyO3git clone https://gitcode.com/gh_mirrors/py/pyo3 maturin new -b pyo3 my-embedded-py在Cargo.toml中確認(rèn)引入了 pyo3 依賴嵌入場(chǎng)景無(wú)需extension-module特性。第 3 步寫最小嵌入代碼use pyo3::prelude::*; fn main() - PyResult() { Python::attach(|py| { let result: i32 py.eval(csum([1, 2, 3]), None, None)?.extract()?; println!(Python says: {result}); Ok(()) }) }py.eval()執(zhí)行一條 Python 表達(dá)式并返回值extract()把它轉(zhuǎn)成 Rust 類型——整個(gè)嵌入流程就這幾行。4 種執(zhí)行 Python 代碼的方式速查官方指南 guide/src/python-from-rust/calling-existing-code.md 總結(jié)了 4 個(gè)核心入口建議直接對(duì)照使用PyModule::import—— 導(dǎo)入現(xiàn)成的 Python 模塊如builtins、os再.getattr(函數(shù)名)調(diào)用Python::eval—— 只跑表達(dá)式并拿返回值如上例Python::run—— 跑語(yǔ)句塊/腳本通過(guò) locals 字典取結(jié)果調(diào)試時(shí)也可用會(huì)直接 panic 的py_run!宏P(guān)yModule::from_code—— 把一段 Python 代碼或多個(gè) .py 文件配合include_str!編譯期內(nèi)聯(lián)當(dāng)作臨時(shí)模塊加載?? 安全提示from_code會(huì)直接編譯執(zhí)行傳入代碼永遠(yuǎn)不要傳入不可信來(lái)源的代碼。調(diào)用細(xì)節(jié)位置參數(shù) / 關(guān)鍵字參數(shù)、call0~call1簡(jiǎn)化 API見 guide/src/python-from-rust/function-calls.md。進(jìn)階讓內(nèi)嵌 Python 導(dǎo)入你寫的 Rust 模塊嵌入場(chǎng)景下最實(shí)用的技巧是雙向打通——在解釋器里import一個(gè) Rust 實(shí)現(xiàn)的模塊pyo3::append_to_inittab!(foo); // 必須在初始化 Python 之前注冊(cè) Python::attach(|py| { py.run(cimport foo; print(foo.add_one(6)), None, None) })append_to_inittab!宏把#[pymodule]模塊注入內(nèi)嵌解釋器的啟動(dòng)表受條件編譯約束時(shí)可用PyModule::new 手動(dòng)寫入sys.modules替代完整示例見 guide/src/python-from-rust/calling-existing-code.md 末尾兩節(jié)。更底層的玩法可以看看純 FFI 示例 pyo3-ffi/examples/sequential/它不依賴 PyO3 安全 API直接演示了子解釋器與 free-threaded Python 的支持方式而 examples/decorator/src/lib.rs 則是擴(kuò)展方向Rust 暴露給 Python的完整工程模板兩者對(duì)照學(xué)習(xí)效果最佳。常見坑與調(diào)試建議問題建議Python 異常沒處理返回類型統(tǒng)一用PyResultT?即可向 Rust 傳播錯(cuò)誤多次初始化報(bào) panicwith_embedded_python_interpreter一個(gè)進(jìn)程只能調(diào)用一次長(zhǎng)生命周期請(qǐng)用Python::attach想釋放 GIL 做并行使用py.allow_threads分離線程參考 guide/src/parallelism.md遇到詭異行為先看 guide/src/debugging.md 與 guide/src/faq.md總結(jié)掌握 PyO3 嵌入 Python 只需記住這張心智地圖入口Python::attach可復(fù)用或with_embedded_python_interpreter一次性執(zhí)行eval跑表達(dá)式、run跑語(yǔ)句、import用模塊、from_code加載代碼雙向append_to_inittab!把 Rust 模塊注冊(cè)進(jìn)內(nèi)嵌解釋器現(xiàn)在你可以把任意 Python 生態(tài)數(shù)據(jù)處理、AI 庫(kù)、腳本資產(chǎn)當(dāng)作引擎裝進(jìn)高性能的 Rust 外殼里了。深入 API 請(qǐng)參考官方指南目錄 guide/src/?!久赓M(fèi)下載鏈接】pyo3Rust bindings for the Python interpreter項(xiàng)目地址: https://gitcode.com/gh_mirrors/py/pyo3創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考