python - PyO3 - 传递类扩展另一个类作为函数参数

标签 python inheritance rust traits pyo3

我有一个 Rust 库,我希望能够从 Python 中使用它。所以我可以使用 PyO3 进行绑定(bind)。
假设我在 Rust 中有以下库:

pub trait Animal {
    fn make_sound();
}

pub struct Dog {}

impl Animal for Dog {
    fn make_sound() {
       println!("whoof whoof");
    }
}

pub struct Cat {}

impl Animal for Cat {
    fn make_sound() {
       println!("miaauwwww");
    }
}

pub fn make_three_sounds(&impl Animal) {
    animal.make_sound();
    animal.make_sound();
    animal.make_sound();
}

该库的用户可以使用结构 Dog 和 Cat 以及函数 make_three_sounds。但他们也可以使用特性 Animal 定义自己的动物,然后将其传递给函数 make_three_sounds。
现在,假设我希望从 Python 中使用这个库。所以我可以使用 PyO3 来制作 Rust -> Python 绑定(bind)。然而,问题是在 Python 中,这会以不同的方式实现。您将拥有一个可以扩展的类,而不是 trait。所以在 Python 中,这个库看起来像这样:
Class Animal:
    def make_sound():
        raise Error("Unimplemented abstract method")

class Dog(Animal):
    def make_sound():
        print("woaggh woafgg")

class Cat(Animal):
    def make_sound():
        print("miaaoww")

def make_three_sounds(a: Animal):
    a.make_sound()
    a.make_sound()
    a.make_sound()
为了创建一个 Dog 和 Cat 类,我只需要在 Dog 和 Cat 结构体上方使用“#[pyclass]”和“#[pymethods]”。问题在于创建一个可以扩展的 Animal 类,然后传递给函数 make_three_sounds。为了创建 Animal 类,我可以创建一个使用 Animal 特征的结构,然后在其上方添加“#[pyclass]”。
但问题是:当 Python 库的用户扩展该类(Animal)然后将其传递给 make_three_sounds 时,它将无法工作,因为 make_three_sounds 必须接受一个实现 trait Animal 的结构,而 Python 对象没有实现它特征(尽管它是扩展实现它的类/结构的类的对象)。我可以制作 make_three_sounds 的包装接受 PyAny 对象的函数,但是我以后如何将该对象传递给实际的 make_three_sounds功能?

最佳答案

我可以看到的一种解决方案如下。
我创建了一个函数 make_three_sounds(PyAny a)这将是 Rust make_three_sounds(&impl Animal a) 的包装器功能。该包装器将接受 PyAny 类型的对象。稍后我将执行以下操作。我将有一个特殊的结构 PyAnimal 实现特征 Animal。该特征将有一个名为 python_object 的属性。 . Python 中的 PyAny 对象(表示扩展 Animal 的类的对象)稍后将分配给该属性 python_object . PyAnimal 必须实现 trait 方法,该方法的实现将在 python_object 上调用该方法。 (PyAny 结构有一个 callmethod 方法,可以调用该对象的任何方法)。该 PyAnimal 对象将被传递给 make_three_sounds(&impl Animal a)功能。所以 PyAnimal 的实现或多或少如下:

struct PyAnimal {
    python_object: PyAny
}

impl Animal for PyAnimal {
   fn make_sound() {
       python_object.call_method('make_sound');
   }
}

关于python - PyO3 - 传递类扩展另一个类作为函数参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63749018/

相关文章:

c# - C#中继承类的问题

rust - 使用 Rust 解引用运算符 &* vs * with Self?

struct - 在 Rust 中设置对象参数的性能

performance - 与 C 相比,Rust 文件 I/O 非常慢。有什么问题吗?

python - 递归函数,最终打印语句

类 java 继承的 VBA 组合

android - 如何在 Kotlin 中为 Any 类型声明扩展 val

python - 在 ipython 中编辑先前定义的类的好方法

python - 跨文件共享的 Python 中的静态变量

Python如何获取cookie的域