这是我的main.rs%文件:

use pyo3::prelude::*;
use pyo3::types::{PyDateTime, PyDate};

fn main() -> () {
    Python::with_gil(|py| {
        let datetime = py.import("datetime").unwrap();
        let my_datetime = datetime.call_method1("datetime", (2022, 3, 28, 0, 0, 0, 0)).unwrap();
        println!("isinstance pydatetime: {:?}", my_datetime.is_instance_of::<PyDateTime>().unwrap());
        println!("isinstance pydate: {:?}", my_datetime.is_instance_of::<PyDate>().unwrap());

        let my_date = datetime.call_method1("date", (2022, 3, 28)).unwrap();
        println!("isinstance pydatetime: {:?}", my_date.is_instance_of::<PyDateTime>().unwrap());
        println!("isinstance pydate: {:?}", my_date.is_instance_of::<PyDate>().unwrap());
    })
}

这是我的Cargo.toml%文件:

[package]
name = "tmp"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
pyo3 = { version = "0.18.0", features = ["auto-initialize"] }

如果我运行上面的命令,我会得到

isinstance pydatetime: true
isinstance pydate: true
isinstance pydatetime: true
isinstance pydate: true

我觉得这有点奇怪,因为直接在Python中运行时,我会得到:

In [27]: import datetime as dt

In [28]: isinstance(my_datetime, dt.datetime)
Out[28]: True

In [29]: isinstance(my_datetime, dt.date)
Out[29]: True

In [30]: isinstance(my_date, dt.datetime)
Out[30]: False

In [31]: isinstance(my_date, dt.date)
Out[31]: True

所以,我本以为

my_date.is_instance_of::<PyDateTime>().unwrap()

也要活到false

为什么不是这样,我如何区分一个对象是datetime还是date,而不求助于更麻烦的方法,比如判断dt.get_type().name()

推荐答案

我已经向PY03提交了一个拉取请求,应该可以解决这个问题:https://github.com/PyO3/pyo3/pull/3071

diff --git a/src/types/datetime.rs b/src/types/datetime.rs
index 85860728568..2c995356e2c 100644
--- a/src/types/datetime.rs
+++ b/src/types/datetime.rs
@@ -228,7 +228,7 @@ pub struct PyDateTime(PyAny);
 pyobject_native_type!(
     PyDateTime,
     crate::ffi::PyDateTime_DateTime,
-    *ensure_datetime_api(Python::assume_gil_acquired()).DateType,
+    *ensure_datetime_api(Python::assume_gil_acquired()).DateTimeType,
     #module=Some("datetime"),
     #checkfunction=PyDateTime_Check
 );

Rust相关问答推荐

如何处理动态 struct 实例化?

使用 struct 外部的属性来改变 struct 的原始方式

如何指定不同的类型来常量Rust中的泛型参数?

将PathBuf转换为字符串

我可以在不收集或克隆的情况下,将一个带有Item=(key,val)的迭代器拆分成单独的key iter和val iter吗?

将一个泛型类型转换为另一个泛型类型

rust 蚀生命周期 不匹配-不一定超过此处定义的生命周期

仅发布工作区的二进制 crate

Rust 中多个 & 符号的内存表示

如何保存指向持有引用数据的指针?

将多维数组转换为切片

全面的 Rust Ch.16.2 - 使用捕获和 const 表达式的 struct 模式匹配

具有在宏扩展中指定的生命周期的枚举变体数据类型

为什么允许重新分配 String 而不是 *&String

为什么 Rust 允许写入不可变的 RwLock?

`map` 调用在这里有什么用吗?

Rustlings 切片原语

从函数返回 u32 的数组/切片

我可以在不调用 .clone() 的情况下在类型转换期间重用 struct 字段吗?

为什么当borrow 变量发生变化时,borrow 变量不会改变?