Rust嵌入Python调用外部库:pyo3无法识别Python解释器问题排查
Rust嵌入Python项目配置与问题排查
项目背景
我正在学习如何在Rust应用中嵌入Python,编写了一个Rust程序,通过永久循环每隔10秒调用Python的requests库从网络时间服务器获取UTC时间,最终目标是将Python BACnet栈集成到Rust应用中。
项目配置
1. main.rs代码
use pyo3::prelude::*; use pyo3::types::IntoPyDict; use std::thread; use std::time::Duration; fn main() -> PyResult<()> { // Safely acquire the GIL and run the Python code Python::with_gil(|py| { // Print the version of Python being used py.run("import sys; print('Python version:', sys.version)", None, None)?; // Import the requests library in Python let requests = py.import("requests")?; loop { // Sleep for 10 seconds thread::sleep(Duration::from_secs(10)); // Execute the Python code to get the current time from a time server let locals = [("requests", requests)].into_py_dict(py); let time_response: String = py.eval( r#" import requests response = requests.get('http://worldtimeapi.org/api/timezone/Etc/UTC') response.json()['datetime'] "#, None, Some(locals) )?.extract()?; // Print the time received from the server println!("Current UTC Time: {}", time_response); } Ok(()) }) }
2. Cargo.toml配置
[package] name = "rust_python_time_fetcher" version = "0.1.0" edition = "2021" [dependencies] pyo3 = { version = "0.21.2", features = ["extension-module"] } [build-dependencies] pyo3-build-config = "0.21.2"
3. build_with_python.sh脚本
#!/bin/bash # Activate the virtual environment source env/bin/activate # Get the path to the Python interpreter PYTHON=$(which python3) # Get the Python version PYTHON_VERSION=$($PYTHON -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')") # Set the path to the Python interpreter export PYO3_PYTHON="$PYTHON" # Set the paths for Python libraries and include files export LD_LIBRARY_PATH="$($PYTHON -c "import sysconfig; print(sysconfig.get_config_var('LIBDIR'))"):$LD_LIBRARY_PATH" export LIBRARY_PATH="$($PYTHON -c "import sysconfig; print(sysconfig.get_config_var('LIBDIR'))"):$LIBRARY_PATH" export PYTHONPATH="$($PYTHON -c "import site; print(site.getsitepackages()[0])"):$PYTHONPATH" # Include and lib directories might vary based on how Python was installed or the distro specifics export CFLAGS="$($PYTHON -c "import sysconfig; print('-I' + sysconfig.get_paths()['include'])")" export LDFLAGS="$($PYTHON -c "import sysconfig; print('-L' + sysconfig.get_config_var('LIBDIR'))")" # Now try running Cargo build again cargo build # Print Python version and path $PYTHON --version which $PYTHON # Print Python includes and libs $PYTHON-config --includes $PYTHON-config --libs
遇到的问题
执行cargo build时出现错误:
> cargo build Compiling pyo3-build-config v0.21.2 error: failed to run custom build command for `pyo3-build-config v0.21.2` Caused by: process didn't exit successfully: `C:\Users\bbartling\Desktop\rust_python_time\target\debug\build\pyo3-build-config-6b34c9835096c15d\build-script-build` (exit code: 1) --- stdout cargo:rerun-if-env-changed=PYO3_CONFIG_FILE cargo:rerun-if-env-changed=PYO3_NO_PYTHON cargo:rerun-if-env-changed=PYO3_ENVIRONMENT_SIGNATURE cargo:rerun-if-env-changed=PYO3_PYTHON cargo:rerun-if-env-changed=VIRTUAL_ENV cargo:rerun-if-env-changed=CONDA_PREFIX cargo:rerun-if-env-changed=PATH --- stderr error: no Python 3.x interpreter found
已尝试操作
在树莓派上运行build_with_python.sh脚本,激活虚拟环境并设置Python库和头文件的必要路径,但仍出现相同错误。
问询问题
- 如何正确配置Rust项目,使其识别并使用虚拟环境中的Python解释器和库?
- 还需执行哪些额外步骤确保pyo3 crate能找到并使用Python解释器?
解决方案
针对问题1:正确配置虚拟环境识别
- 直接指定虚拟环境Python路径
避免which python3的路径歧义,直接用虚拟环境内Python的绝对路径:# 替换脚本中PYTHON变量赋值 PYTHON="./env/bin/python3" - 修正pyo3特性配置
当前启用的extension-module特性是用于编译Python扩展模块的,和嵌入Python的需求不符。修改Cargo.toml:[dependencies] pyo3 = { version = "0.21.2" } - 验证虚拟环境激活状态
手动激活虚拟环境后,确认python3 --version显示的是虚拟环境内的版本,再执行cargo build。
针对问题2:确保pyo3找到Python解释器的额外步骤
- 安装Python开发包
树莓派默认可能缺少Python头文件和库,安装对应版本的开发包(以Python3.10为例):sudo apt-get install python3.10-dev - 显式指定Python版本
设置环境变量让pyo3直接匹配版本:export PYO3_PYTHON=3.10 - 清理Cargo缓存
清除之前的错误缓存后重新构建:cargo clean cargo build - 检查环境变量有效性
运行cargo build前,手动验证:echo $PYO3_PYTHON # 应输出虚拟环境内Python的绝对路径
内容的提问来源于stack exchange,提问作者bbartling
相关产品推荐
相关产品推荐

