在Python中,为什么isinstance函数认为datetime是datetime.date的实例?

1 投票
1 回答
745 浏览
提问于 2025-04-18 04:55

问题在于,isinstance 函数认为 datetime.datetime 的实例也是 datetime.date 的实例。

为什么会这样呢?这合理吗?

Python 2.7.4 (default, Sep 26 2013, 03:20:26) 
[GCC 4.7.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import datetime
>>> d = datetime.datetime(2014, 4, 30, 15, 9, 4, 218466)
>>> isinstance(d, datetime.datetime)
True
>>> isinstance(d, datetime.date)
True

这导致 Django 1.4.10(我没有检查其他版本)错误地发出一个运行时警告,声称一些完全支持时区的日期时间其实不支持,因为有一个规则(在这里)说日期实例总是“天真”的。这个警告是在 django/db/models/fields/init.py 的第 759 行触发的。也许这是对“日期类型的对象总是天真”的理解错误,他们应该使用 type 函数来检查类型,而不是使用 isinstance(或者更好的是,使用 django.utils.timezone.is_aware 函数)。

那么这是 Django 的一个 bug,还是 Python 的 isinstance 函数的行为有问题?或者两者都有?还是只是我搞错了?

>>> from django.utils.timezone import is_aware, utc
>>> d = datetime.datetime(2014, 4, 30).replace(tzinfo=utc)
>>> is_aware(d)
True
>>> isinstance(d, datetime.date)
True

1 个回答

7
>>> issubclass(datetime.datetime, datetime.date)
True

datetimedate 的一个子类,也就是说,所有的 datetime 其实都是 date

我不太清楚 Django 是怎么处理这个的。说所有不是 datetimedate 都是“天真”的,这样说是有道理的,但我不确定 Django 实际上是否是这样做的。

撰写回答