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

使用Virtualenv结合PyO3时遭遇ModuleNotFoundError(pyarrow缺失)

解决PyO3无法识别虚拟环境Python依赖的问题

问题背景

在Rust项目中结合Virtualenv/pyenv虚拟环境使用PyO3时,PyO3始终调用系统Python而非虚拟环境,导致pyarrow等依赖找不到——即使已在虚拟环境中安装对应包。相关代码与依赖如下:

代码与依赖

main.rs

use polars::prelude::*;
use pyo3::{prelude::*, types::PyModule};
use pyo3_polars::PyDataFrame;

fn main() -> PyResult<()> {
    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(())
    })
}

test.py

def test(x):
    import pyarrow

    import sys
    print(sys.executable, sys.path)

    # manipulate dataframe x
    return x

Cargo.toml

[dependencies]
pyo3 = { version = "0.20.0", features = ["auto-initialize"] }
polars = "0.35.4"
pyo3-polars = "0.9.0"

问题现象

  1. 激活虚拟环境后执行cargo run,报错ModuleNotFoundError: No module named 'pyarrow'
  2. 注释import pyarrow后,错误仍来自pyo3-polars的类型转换逻辑,且输出显示PyO3使用系统Python路径
  3. 切换到pyenv虚拟环境后问题依旧

解决方案

PyO3的auto-initialize特性会自动查找系统Python,要让它绑定虚拟环境的Python,可通过以下两种方式解决:

方式1:环境变量指定(推荐)

激活虚拟环境后,设置PYO3_PYTHON环境变量指向虚拟环境的Python可执行文件,再运行项目:

# 激活Virtualenv环境
. venv/bin/activate
# 绑定虚拟环境Python路径
export PYO3_PYTHON="$VIRTUAL_ENV/bin/python3"
# 运行项目
cargo run

对于pyenv环境:

pyenv activate your-env-name
# 绑定pyenv环境的Python路径
export PYO3_PYTHON="$(pyenv which python)"
cargo run

方式2:手动初始化Python解释器

修改Cargo.toml移除auto-initialize特性:

pyo3 = { version = "0.20.0", features = [] }

在Rust代码中手动指定Python路径并初始化:

use polars::prelude::*;
use pyo3::{prelude::*, types::PyModule};
use pyo3_polars::PyDataFrame;
use pyo3::ffi::Py_SetProgramName;
use std::ffi::CString;

fn main() -> PyResult<()> {
    // 替换为你的虚拟环境Python路径
    let python_path = "/path/to/your/venv/bin/python3";
    let c_path = CString::new(python_path).unwrap();
    
    unsafe {
        Py_SetProgramName(c_path.as_ptr());
    }

    Python::with_gil(|py| {
        // 将虚拟环境的site-packages加入Python路径
        let sys = py.import("sys")?;
        let venv_site_packages = "/path/to/your/venv/lib/python3.x/site-packages"; // 替换为对应路径
        sys.call_method1("append", (venv_site_packages,))?;

        let code = include_str!("./test.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(())
    })
}

验证生效

修改test.py添加验证输出:

def test(x):
    import sys
    print("当前Python路径:", sys.executable)
    import pyarrow
    print("PyArrow版本:", pyarrow.__version__)
    return x

运行后若输出虚拟环境的Python路径及PyArrow版本,说明问题解决。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 18:02:49