You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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库和头文件的必要路径,但仍出现相同错误。

问询问题

  1. 如何正确配置Rust项目,使其识别并使用虚拟环境中的Python解释器和库?
  2. 还需执行哪些额外步骤确保pyo3 crate能找到并使用Python解释器?

解决方案

针对问题1:正确配置虚拟环境识别

  1. 直接指定虚拟环境Python路径
    避免which python3的路径歧义,直接用虚拟环境内Python的绝对路径:
    # 替换脚本中PYTHON变量赋值
    PYTHON="./env/bin/python3"
    
  2. 修正pyo3特性配置
    当前启用的extension-module特性是用于编译Python扩展模块的,和嵌入Python的需求不符。修改Cargo.toml:
    [dependencies]
    pyo3 = { version = "0.21.2" }
    
  3. 验证虚拟环境激活状态
    手动激活虚拟环境后,确认python3 --version显示的是虚拟环境内的版本,再执行cargo build。

针对问题2:确保pyo3找到Python解释器的额外步骤

  1. 安装Python开发包
    树莓派默认可能缺少Python头文件和库,安装对应版本的开发包(以Python3.10为例):
    sudo apt-get install python3.10-dev
    
  2. 显式指定Python版本
    设置环境变量让pyo3直接匹配版本:
    export PYO3_PYTHON=3.10
    
  3. 清理Cargo缓存
    清除之前的错误缓存后重新构建:
    cargo clean
    cargo build
    
  4. 检查环境变量有效性
    运行cargo build前,手动验证:
    echo $PYO3_PYTHON
    # 应输出虚拟环境内Python的绝对路径
    

内容的提问来源于stack exchange,提问作者bbartling

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 17:24:53