PyO3中如何区分PyDateTime与PyDate实例?
问题原因
PyO3 0.18.0版本中,PyDateTime类型的实例检查逻辑存在异常,错误地将Python的datetime.date对象判定为datetime.datetime类型的实例,这与Python原生的isinstance行为不符。本质原因是该版本对datetime模块类型的绑定或实例检查逻辑未正确遵循Python的继承规则——Python中datetime.datetime是datetime.date的子类,但反向判定不成立。
正规区分方法
无需依赖类型名称判断,可通过以下两种方式正确区分:
方式一:结合PyDate和PyDateTime的实例检查
利用Python中datetime.datetime是datetime.date子类的特性,先检查是否为PyDateTime实例(若是则为datetime.datetime),否则再检查是否为PyDate实例:
use pyo3::types::{PyDate, PyDateTime}; use pyo3::PyAny; fn is_date(obj: &PyAny) -> bool { obj.is_instance_of::<PyDate>().unwrap() && !obj.is_instance_of::<PyDateTime>().unwrap() } fn is_datetime(obj: &PyAny) -> bool { obj.is_instance_of::<PyDateTime>().unwrap() }
方式二:直接调用Python原生的类型检查
通过导入Python的datetime模块,获取原生的date和datetime类型对象,再调用is_instance方法进行检查,结果与Python环境完全一致:
use pyo3::types::PyModule; use pyo3::{PyAny, Python}; fn get_date_type(py: Python<'_>) -> &PyAny { PyModule::import(py, "datetime") .unwrap() .getattr("date") .unwrap() } fn get_datetime_type(py: Python<'_>) -> &PyAny { PyModule::import(py, "datetime") .unwrap() .getattr("datetime") .unwrap() } fn is_date(obj: &PyAny) -> bool { let py = obj.py(); obj.is_instance(get_date_type(py)).unwrap() && !obj.is_instance(get_datetime_type(py)).unwrap() } fn is_datetime(obj: &PyAny) -> bool { let py = obj.py(); obj.is_instance(get_datetime_type(py)).unwrap() }
内容的提问来源于stack exchange,提问作者ignoring_gravity
相关产品推荐
相关产品推荐

