【问题标题】:Get Python ID as a number for Py03 PyAny object in Rust获取 Python ID 作为 Rust 中 Py03 PyAny 对象的数字
【发布时间】:2023-01-16 22:34:29
【问题描述】:

我正在使用 Py03 在 Rust 中构建一个 python 模块。我在 Rust 中有一个类,它接受 PyAny 来引用 Python 中的对象。作为 Rust 类的哈希函数的一部分,我想在 Rust 的哈希函数中使用此对象的 Python ID,这样如果在 Rust 类的多个版本中引用了相同的 Python 对象,我可以对 Rust 类进行重复数据删除。我可以在 Rust 的 PyAny 对象中看到 python ID,但无法弄清楚如何将它变成一个我可以传递给哈希器的纯数字。

例如,我在 Rust 中有以下内容:

#[pyclass]
pub struct MyClass {
    obj: Option<Py<PyAny>>,
}
#[pymethods]
impl MyClass {
    #[new]
    fn new(obj: Option<Py<PyAny>>) -> Self {
        if obj.is_some() {
            println!("Obj: {:?}", obj.as_ref());
        }
        Self { obj }
    }
}

然后,我可以在 Python 中运行:

obj = [1,2,3,4]
print(hex(id(obj)))
# '0x103da9100'
MyClass(obj)
# Obj: Some(Py(0x103da9100))

Python 和 Rust 都显示相同的 ID 数字,这很好,但我如何才能将这个数字 0x103da9100 放入 Rust 变量中?看起来 PyAny 只是一个元组结构,所以我尝试了以下但 Rust 抱怨 PyAny 的字段是私有的:

let obj_id = obj?.0;

【问题讨论】:

  • 您可以使用as_ptr 获取PyAny 元组的内容,但我不确定如何从那里获取 id(除非 id 只是指针的值)。

标签: python rust pyo3


【解决方案1】:

您代码中的objOption&lt;Py&lt;PyAny&gt;&gt; 类型。要获得底层 FFI 指针(在您的情况下是列表),您需要先解构您的选项。然后使用destructured_object.as_ptr()Py&lt;T&gt;获取T

#[pymethods]
impl MyClass {
    #[new]
    fn new(obj: Option<Py<PyAny>>) -> Self {
        if let Some(ref obj1) = obj { // obj1 will be of type `Py<PyList> in case of List`
            let concreate_type = obj1.as_ptr(); // Get PyList from `Py<PyList>
            println!("{}", concreate_type as isize)

        }

        Self { obj }
    }
}

现在您在concreate_type 中有了原始指针,您可以将指针类型转换为isize 以获取对象的内存位置。这正是 Cpython 作为实现的一部分返回的内容。有关详细信息,请参阅id.__doc__

>>> print(id.__doc__)
Return the identity of an object.

This is guaranteed to be unique among simultaneously existing objects.
(CPython uses the object's memory address.)
>>> 
>>> a = [1, 2, 3, 4]
>>> id(a)
4357355968
>>> 
>>> from myid import MyClass
>>> MyClass(a)
4357355968

【讨论】:

  • @cafce25 抱歉,我恢复了编辑,因为 python 中的 id 函数返回非十六进制格式。
猜你喜欢
  • 2022-07-29
  • 2022-11-12
  • 1970-01-01
  • 1970-01-01
  • 2020-08-17
  • 2020-04-15
  • 2022-11-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多