ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

PyO3核心注解详解:pymodule与pyfunction两大宏如何把Rust函数暴露给Python

2026/9/21 15:09:44 拓冰建站 浏览量
PyO3核心注解详解:pymodule与pyfunction两大宏如何把Rust函数暴露给Python PyO3核心注解详解#pymodule与#pyfunction两大宏如何把Rust函数暴露给Python【免费下载链接】pyo3Rust bindings for the Python interpreter项目地址: https://gitcode.com/gh_mirrors/py/pyo3PyO3 是 Python 解释器的 Rust 绑定框架让你用 Rust 编写高性能扩展并直接在 Python 中调用。其中#pymodule与#pyfunction是 PyO3 最核心的两大注解宏前者负责创建 Python 模块入口后者把单个 Rust 函数变成 Python 可调用函数。本文用尽量少的代码带你彻底看懂这两个宏是如何协作工作的。一、为什么需要这两大宏默认情况下Python 对编译后的 Rust 代码是看不见的——桥梁不通Rust 函数写得再快也没法被调用。PyO3 用 Rust 的过程式宏procedural macros补上这座桥思路分成两步#pyfunction—— 给 Rust 函数贴上可暴露标签自动处理参数转换与错误#pymodule—— 生成模块初始化函数把这些函数挂到模块上供 Python 导入。这正是官方指南中阐述的设计哲学详见 guide/src/rust-from-python.md。二、#pyfunction一行注解把 Rust 函数变成 Python 函数给一个普通的 Rust 函数加上一行注解即可#[pyfunction] fn double(x: usize) - usize { x * 2 }这一行背后PyO3 自动帮你完成三件事参数自动转换Python 的int、str、list等会自动转为对应的 Rust 类型文档注释变 docstring函数上方的///注释直接成为 Python 侧的函数文档错误自动转换函数返回PyResult时Rust 错误会自动转为 Python 异常。还可以用#[pyo3(...)]参数进一步定制完整说明见 guide/src/function.md参数作用#[pyo3(name 新名字)]修改暴露给 Python 的函数名#[pyo3(signature (a, b1))]定义默认值与关键字参数签名#[pyo3(pass_module)]把当前模块作为第一个参数传入函数三、#pymodulePython 模块的大门#[pyfunction]只是把函数备好要真正被import还得靠#[pymodule]生成模块的初始化函数即PyInit_xxx。常见有两种写法写法一命令式注册最常用真实示例见 examples/word-count/src/lib.rs#[pymodule] fn word_count(m: Bound_, PyModule) - PyResult() { m.add_function(wrap_pyfunction!(search, m)?) }写法二声明式导出把函数直接写在模块里自动导出见 guide/src/module.md#[pymodule] mod my_extension { use pyo3::prelude::*; #[pyfunction] fn double(x: usize) - usize { x * 2 } }另外两个实用细节模块文档在#[pymodule]上方写/// This module is implemented in Rust.Python 里print(module.__doc__)就能看到见 guide/src/module.md#[pymodule_init]可在模块初始化时执行任意自定义代码见 guide/src/module.md。四、⚠️ 新手最常踩的两个坑模块名必须与文件名一致模块名要和.so/.pyd文件名相同否则 Python 会报ImportError: dynamic module does not define module export function。想改名请使用#[pyo3(name ...)]参数实例见 examples/getitem/src/lib.rs详细说明见 guide/src/module.md定义了函数却忘了注册在写法一中如果只写了#[pyfunction]却没有m.add_function(...)Python 调用时会抛AttributeError。五、两大宏协作一次调用的完整链路以 examples/word-count 为例Python 调用一次 Rust 函数完整链路只有 4 步Python: import word_count → ① #pymodule 生成 PyInit_word_count触发模块初始化 → ② wrap_pyfunction! 把 #pyfunction 函数逐一注册到模块 → ③ Python 调用 search(...)PyO3 自动完成参数转换 → ④ 返回值自动转回 Python 类型一句话总结#pyfunction 定义能调用什么#pymodule 决定注册到哪里。两者配合用 Rust 写 Python 扩展只需要一行注解加一行注册。写好之后用maturin等工具构建安装即可直接在 Python 中import使用。六、延伸阅读模块章节官方指南guide/src/module.md函数章节官方指南guide/src/function.md宏的实现源码pyo3-macros-backend/src/module.rs、pyo3-macros-backend/src/pyfunction.rs可运行的完整示例examples/word-count/【免费下载链接】pyo3Rust bindings for the Python interpreter项目地址: https://gitcode.com/gh_mirrors/py/pyo3创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考