
本文介绍了在使用 PyO3 将 Python 嵌入 Rust 项目时,如何正确配置和使用虚拟环境,以解决依赖包无法找到的问题。通过手动初始化 Python 解释器,并设置正确的 Python 前缀,确保 PyO3 使用指定的虚拟环境,从而避免 ModuleNotFoundError 错误,保证项目依赖的正确性。
在使用 PyO3 进行 Rust 和 Python 混合编程时,尤其是在 Rust 中嵌入 Python 代码的情况下,正确配置虚拟环境至关重要。默认情况下,PyO3 可能会使用全局 Python 安装,导致无法找到在虚拟环境中安装的依赖包,例如 pyarrow。本文将详细介绍如何手动初始化 Python 解释器,并指定虚拟环境路径,从而确保 PyO3 使用正确的 Python 环境。
手动初始化 Python 解释器
PyO3 默认情况下会自动初始化 Python 解释器,但为了能够使用虚拟环境,我们需要禁用此功能,并手动进行初始化。这需要移除 pyo3 依赖中的 auto-initialize feature。
首先,在 Cargo.toml 文件中,修改 pyo3 依赖:
立即学习“Python免费学习笔记(深入)”;
[dependencies]pyo3 = { version = "0.20.0", features = [] } # 移除 auto-initializepolars = "0.35.4"pyo3-polars = "0.9.0"libc = "0.2.150"
然后,在 Rust 代码中,我们需要编写一个函数来手动初始化 Python 解释器,并指定虚拟环境的路径。以下是一个示例函数:
use std::mem::size_of;use std::ptr::addr_of_mut;use libc::wchar_t;use pyo3::ffi::*;fn init_pyo3_with_venv(env_dir: &str) { unsafe { fn check_exception(status: PyStatus, config: &mut PyConfig) { unsafe { if PyStatus_Exception(status) != 0 { PyConfig_Clear(config); if PyStatus_IsExit(status) != 0 { std::process::exit(status.exitcode); } Py_ExitStatusException(status); } } } let mut config = std::mem::zeroed::(); PyConfig_InitPythonConfig(&mut config); config.install_signal_handlers = 0; // `wchar_t` is a mess. let env_dir_utf16; let env_dir_utf32; let env_dir_ptr; if size_of::() == size_of::() { env_dir_utf16 = env_dir .encode_utf16() .chain(std::iter::once(0)) .collect::<Vec>(); env_dir_ptr = env_dir_utf16.as_ptr().cast::(); } else if size_of::() == size_of::() { env_dir_utf32 = env_dir .chars() .chain(std::iter::once(' ')) .collect::<Vec>(); env_dir_ptr = env_dir_utf32.as_ptr().cast::(); } else { panic!("unknown encoding for `wchar_t`"); } check_exception( PyConfig_SetString( addr_of_mut!(config), addr_of_mut!(config.prefix), env_dir_ptr, ), &mut config, ); check_exception(Py_InitializeFromConfig(&config), &mut config); PyConfig_Clear(&mut config); PyEval_SaveThread(); }}
这个函数接受虚拟环境的目录作为参数,并使用 Python 的 C API 来初始化解释器,并将虚拟环境的路径设置为 Python 的前缀。
讯飞智作-虚拟主播
讯飞智作是一款集AI配音、虚拟人视频生成、PPT生成视频、虚拟人定制等多功能的AI音视频生产平台。已广泛应用于媒体、教育、短视频等领域。
6 查看详情
在 main 函数中使用虚拟环境
在 main 函数中,我们需要先调用 init_pyo3_with_venv 函数,然后再使用 PyO3 与 Python 交互。
use polars::prelude::*;use pyo3::{prelude::*, types::PyModule};use pyo3_polars::PyDataFrame;fn main() -> PyResult { // 获取当前目录,并拼接虚拟环境目录 let env_dir = std::env::current_dir()?.join(".venv"); if !env_dir.is_dir() { panic!("请在正确的目录下运行,确保存在 .venv 目录"); } // 初始化 Python 解释器,并指定虚拟环境路径 init_pyo3_with_venv(env_dir.to_str().unwrap()); let code = include_str!("./test.py"); Python::with_gil(|py| { let activators = PyModule::from_code(py, code, "activators.py", "activators")?; let df: DataFrame = df!( "integer" => &[1, 2, 3, 4, 5], "float" => &[4.0, 5.0, 6.0, 7.0, 8.0], ) .unwrap(); let relu_result: PyDataFrame = activators .getattr("test")? .call1((PyDataFrame { 0: df },))? .extract()?; Ok(()) })}
请确保在运行 Rust 代码之前,已经创建了虚拟环境,并在其中安装了所需的 Python 依赖包,例如 pyarrow。
Python 代码示例
以下是一个简单的 Python 脚本示例,用于测试虚拟环境是否配置正确:
# test.pydef test(x): import sys print(sys.executable, sys.path, sys.prefix) import pyarrow # manipulate dataframe x return x
这个脚本会打印 Python 解释器的路径、模块搜索路径和前缀,以及尝试导入 pyarrow 模块。如果虚拟环境配置正确,pyarrow 应该能够成功导入。
注意事项
确保在运行 Rust 代码之前,已经激活了虚拟环境。确保虚拟环境中安装了所有需要的 Python 依赖包。虚拟环境的目录路径需要正确指定。libc 依赖是手动初始化 Python 解释器所必需的。
总结
通过手动初始化 Python 解释器,并指定虚拟环境路径,我们可以确保 PyO3 在 Rust 项目中正确使用虚拟环境,从而避免依赖包无法找到的问题。这种方法虽然需要一些额外的配置,但可以提高项目的可移植性和可维护性。
以上就是使用 PyO3 嵌入 Python 时配置虚拟环境的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/617101.html
微信扫一扫
支付宝扫一扫