如何在Rust中通过PyO3选择正确的pyenv虚拟环境?
PyO3中sys.executable显示Rust二进制路径的问题解决
问题本质
你看到的sys.executable显示Rust二进制路径是Python嵌入模式下的正常行为。当PyO3通过默认的auto-initialize特性自动初始化Python解释器时,Python C API会将当前运行的进程(即你的Rust二进制文件)路径设为sys.executable,而非系统中独立的Python解释器路径。
但从输出的sys.path可以确认:PyO3已经正确链接到了你pyenv激活的3.10.11环境,该环境下的所有Python包都能正常被导入和使用。
解决办法
如果必须让sys.executable显示正确的Python解释器路径,可以手动设置该属性:
方法1:硬编码路径(适合固定环境)
修改你的main.rs代码,在初始化Python后手动指定sys.executable:
use pyo3::prelude::*; fn main() -> PyResult<()> { Python::with_gil(|py| { // 手动设置sys.executable为pyenv的Python路径 let sys = py.import("sys")?; sys.setattr("executable", "/Users/smartinez/.pyenv/versions/3.10.11/bin/python")?; // 原有业务代码 py.run(r#" import pkg_resources installed_packages = pkg_resources.working_set installed_packages_list = sorted(["%s==%s" % (i.key, i.version) for i in installed_packages]) for package in installed_packages_list: print(package) "#, None, None)?; py.run(r#" import sys print(f"executable: {sys.executable}") print(f"path: {sys.path}") "#, None, None)?; Ok(()) }) }
方法2:通过环境变量传递(灵活适配不同环境)
避免硬编码路径,从环境变量中读取Python解释器路径:
use pyo3::prelude::*; use std::env; fn main() -> PyResult<()> { Python::with_gil(|py| { let sys = py.import("sys")?; // 从环境变量PYTHON_EXECUTABLE中读取路径 if let Ok(python_path) = env::var("PYTHON_EXECUTABLE") { sys.setattr("executable", python_path)?; } // 原有业务代码 py.run(r#" import pkg_resources installed_packages = pkg_resources.working_set installed_packages_list = sorted(["%s==%s" % (i.key, i.version) for i in installed_packages]) for package in installed_packages_list: print(package) "#, None, None)?; py.run(r#" import sys print(f"executable: {sys.executable}") print(f"path: {sys.path}") "#, None, None)?; Ok(()) }) }
运行前先设置环境变量:
export PYTHON_EXECUTABLE=$(which python) cargo run
额外说明
如果你的需求只是确保使用正确的Python环境(比如导入该环境下的包),无需修改sys.executable——当前的sys.path已经正确指向pyenv的3.10.11环境,所有依赖都能正常加载。PyO3在编译时会自动链接到当前激活的Python环境,这也是sys.path正确的原因。
内容的提问来源于stack exchange,提问作者seve
相关产品推荐
相关产品推荐

