【问题标题】:How to structure a mixed Python Rust package with PyO3如何使用 PyO3 构建混合 Python Rust 包
【发布时间】:2021-09-04 18:05:25
【问题描述】:

我正在寻找有关如何构建一个 Python 包的信息,该包包含一个用 Rust 编写的扩展模块,这两种语言是混合的。我正在将 pyO3 用于 FFI,但似乎找不到有关如何执行此操作的示例。 具体来说:我的 rust 库公开了一种类型,该类型后来被 python 类包装。 只有 python 类应该为以后的用户公开,并且包应该是结构化的,这样它就可以被推送到 PyPI。

例如:

生锈的一面

#[pyclass]
pub struct Point {
    x: f64,
    y: f64 
}

#[pymethods]
impl Point {
    #[new]
    pub fn new(x: f64, y: f64) -> Self { Self{x, y} }
}

在 python 方面

from ??? import Point

class Points:
    points: List[Point] 
    
    def __init__(self, points: List[Tuple[float, float]]):
        self.points = []
        for point in points:
            x, y = point
            self.points.append(Point(x, y))

我会感谢任何信息、来源、示例等!

【问题讨论】:

  • 我认为这可能与 StackOverflow 无关,但 see here.

标签: python rust package ffi pyo3


【解决方案1】:

我找到了一种使用 Maturin 的方法。 因此,如果其他人试图找出如何做到这一点,这里有一种方法。

项目需要有如下结构:

my_project
├── Cargo.toml
├── my_project
│   ├── __init__.py
│   └── sum.py
└── src
    └── lib.rs

Cargo.toml 可以是:

[package]
name = "my_project"
version = "0.1.0"
edition = "2018"

[lib]
name = "my_project"
crate-type = ["cdylib"]

[dependencies.pyo3]
version = "0.14.5"
features = ["extension-module"]

lib.rs 的一个例子是:

use pyo3::prelude::*;

#[pyfunction]
fn sum_as_string(a: usize, b: usize) -> PyResult<String> {
    Ok((a + b).to_string())
}

#[pymodule]
fn my_project(_py: Python, m: &PyModule) -> PyResult<()> {
    m.add_function(wrap_pyfunction!(sum_as_string, m)?)?;
    Ok(())
}

现在在 sum.py 中可以访问该函数(在开发过程中使用maturin develop 之后,以及在maturin build 之后自动发布时):

from .my_project import sum_as_string

class Sum:
    sum: str
    
    def __init__(self, lhs: int, rhs: int):
        self.sum = sum_as_string(lhs, rhs)

_init _.py 文件例如只能公开 Sum 类:

from .sum import Sum

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-09
    • 1970-01-01
    • 2022-12-04
    • 2023-03-07
    相关资源
    最近更新 更多