当前位置: 代码迷 >> python >> Python如何在内部存储日期时间?
  详细解决方案

Python如何在内部存储日期时间?

热度:100   发布时间:2023-06-19 09:08:34.0

我发现似乎是正确的文件,但我需要一些帮助,因为C不是我的力量。

>>> import datetime
>>> import sys
>>> d = datetime.datetime.now()
>>> sys.getsizeof(d)
48
>>> d = datetime.datetime(2018, 12, 31, 23, 59, 59, 123)
>>> sys.getsizeof(d)
48

因此,时区不知道的日期时间对象需要48个字节。 查看PyDateTime_DateTimeType ,它似乎是PyDateTime_DateTypePyDateTime_TimeType 也许还_PyDateTime_BaseTime

从查看代码,我的印象是YYYY-mm-dd HH:MM:ss每个字段都存储了一个组件,意思是:

  • 年份:例如int(例如int16_t将是16位)
  • 月:例如int8_t
  • 日:例如int8_t
  • 小时:例如int8_t
  • 分钟:例如int8_t
  • 第二:例如int8_t
  • 微秒:例如uint16_t

但是,这将是2 * 16 + 5 * 8 = 72位= 9字节而不是48字节,因为Python告诉我。

我对datetime内部结构的假设在哪里错了? 我怎么能在代码中看到这个?

(我想这可能在Python实现之间有所不同 - 如果是这样,请关注cPython)

您错过了图片的关键部分:实际的日期时间结构定义,位于 。 那里也有重要的评论。 以下是一些关键摘录:

/* Fields are packed into successive bytes, each viewed as unsigned and
 * big-endian, unless otherwise noted:
 *
 * byte offset
 *  0           year     2 bytes, 1-9999
 *  2           month    1 byte, 1-12
 *  3           day      1 byte, 1-31
 *  4           hour     1 byte, 0-23
 *  5           minute   1 byte, 0-59
 *  6           second   1 byte, 0-59
 *  7           usecond  3 bytes, 0-999999
 * 10
 */

...

/* # of bytes for year, month, day, hour, minute, second, and usecond. */
#define _PyDateTime_DATETIME_DATASIZE 10

...

/* The datetime and time types have hashcodes, and an optional tzinfo member,
 * present if and only if hastzinfo is true.
 */
#define _PyTZINFO_HEAD          \
    PyObject_HEAD               \
    Py_hash_t hashcode;         \
    char hastzinfo;             /* boolean flag */

...

/* All datetime objects are of PyDateTime_DateTimeType, but that can be
 * allocated in two ways too, just like for time objects above.  In addition,
 * the plain date type is a base class for datetime, so it must also have
 * a hastzinfo member (although it's unused there).
 */

...

#define _PyDateTime_DATETIMEHEAD        \
    _PyTZINFO_HEAD                      \
    unsigned char data[_PyDateTime_DATETIME_DATASIZE];

typedef struct
{
    _PyDateTime_DATETIMEHEAD
} _PyDateTime_BaseDateTime;     /* hastzinfo false */

typedef struct
{
    _PyDateTime_DATETIMEHEAD
    unsigned char fold;
    PyObject *tzinfo;
} PyDateTime_DateTime;          /* hastzinfo true */

您看到的48字节计数如下所示:

  • 8字节引用计数
  • 8字节类型指针
  • 8字节缓存哈希
  • 1字节“hastzinfo”标志
  • 7字节填充
  • 包含日期时间数据的10字节手动打包char[10]
  • 6字节填充

当然,这是所有实施细节。 它可能在不同的Python实现,或不同的CPython版本,或32位CPython构建,或CPython调试构建上有所不同(当使用Py_TRACE_REFS定义编译CPython时,PyObject_HEAD中有额外的东西)。

  相关解决方案