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

2023-12-08

I found _datetimemodule.c这似乎是正确的文件,但我需要一些帮助,因为 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_DateType and a PyDateTime_TimeType。或许还有_PyDateTime_BaseTime?

通过查看代码,我的印象是为每个字段存储一个组件YYYY-mm-dd HH:MM:ss, 意义:

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

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

我对日期时间内部结构的假设哪里错误?我如何在代码中看到这一点?

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


您缺少图片的关键部分:实际的日期时间结构定义,位于Include/datetime.h。里面也有重要的评论。以下是一些关键摘录:

/* 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 */

另外,请注意以下事项lines in Modules/_datetimemodule.c:

static PyTypeObject PyDateTime_DateTimeType = {
    PyVarObject_HEAD_INIT(NULL, 0)
    "datetime.datetime",                        /* tp_name */
    sizeof(PyDateTime_DateTime),                /* tp_basicsize */

That tp_basicsize线说sizeof(PyDateTime_DateTime), not sizeof(_PyDateTime_BaseDateTime),并且该类型没有实现任何特殊的__sizeof__处理。这意味着datetime.datetimetype 将其实例大小报告为时区感知日期时间的大小,即使对于不感知的实例也是如此。

您看到的 48 字节计数细分如下:

  • 8 字节引用计数
  • 8字节类型指针
  • 8 字节缓存哈希
  • 1 字节“hastzinfo”标志
  • 10字节手动打包unsigned char[10]包含日期时间数据
  • 1 字节“折叠”标志(夏令时相关)
  • 4 字节填充,用于对齐 tzinfo 指针
  • 8字节tzinfo指针

即使您的不知情实例的实际内存布局没有折叠标志或 tzinfo 指针,情况也是如此。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python内部如何存储日期时间? 的相关文章

随机推荐

  • 将 8 位整数转换为 dd/mm/yyyy [重复]

    这个问题在这里已经有答案了 所以我在我的 PHP 脚本中有这个函数 它应该将日期作为 8 位整数 例如01042012并将其转换为01 04 2012用于显示 目前我正在尝试使用 phpdate 函数如下 int 01042012 date
  • 以编程方式动态生成 Azure Function 的访问代码

    我有几个 Azure 函数 用 c 编写 我已将其 URL 提供给不同的团队来调用 调用 我注意到后缀的访问代码始终相同 因此存在安全风险 有没有一种方法可以让我们以编程方式动态生成 Azure 函数的访问代码并将其附加到函数的 URL 中
  • 自定义圆形进度条,图像位于中心[关闭]

    Closed 这个问题需要多问focused 目前不接受答案 对于我的 Android 应用程序 我想将图像放入circular progress bar 预期设计 http hpics li cd6acba 关于如何做到这一点有什么想法吗
  • 调用存储在 std 映射中的成员函数指针

    我将映射存储在一个类中 该类以字符串作为键 以指向成员函数的指针作为值 我在调用正确的函数时遇到问题 抛出函数指针 这是代码 include
  • 无法安装弹性表

    我安装时遇到问题Flextable 这似乎是因为gdtools包裹 看起来像gdtools依赖 dylib 文件 有任何想法吗 gt install packages flextable There is a binary version
  • Python:如何引用实例名称? [复制]

    这个问题在这里已经有答案了 我使用以下代码收集实例 class Hand instances def init self Hand instances append self self value 5 def do something se
  • 在 EC2 实例上运行 jupyter 笔记本

    我在我的 AWS 账户上设置了一个 cloud 9 实例 我使用诗歌作为我的包管理器并安装了 jupyter 笔记本 当我运行命令时poetry run jupyter notebook它像平常一样运行 但是当我按下链接时 他们说无法访问该
  • 为什么不能在带有背景的锚元素上设置行高? [复制]

    这个问题在这里已经有答案了 我刚刚意识到带有背景的锚标记只会继承它们的行高 并且您只能通过将锚设置为显示来直接设置它 inline block 为什么是这样 http jsfiddle net moefinley 3H3y5 ul li a
  • Atmel SAM3X 双组切换不起作用

    我目前正在使用 Atmel SAM3X8 ARM 微控制器 该微控制器具有双组 2 x 256KB 闪存 我正在尝试实现固件更新功能 将新固件放入当前未使用的闪存库中 完成后使用闪存重新映射交换库以运行新固件 数据表指出 为此我需要设置 G
  • Roxygen2:记录重载 R 基函数时用作 S4 的 S3 类(cor)

    我有以下背景 我确实超载cor基本函数 以便我在我的包 R 文件中包含以下语句 export setGeneric cor 现在我想为我的对象创建一个特定的函数 名为stranger 这里为了简单起见 我只认为我的对象是一个 data ta
  • Selenium Webdriver:Firefox 与 PhantomJS 的 HTML 呈现方式不同

    我正在 Node JS 中使用 Selenium Webdriver 进行 Google 搜索 当我在本地计算机上将浏览器设置为 Firefox 时 Google 结果页面将按预期呈现 这和我作为人类进行谷歌搜索时看到的一样 现在 我尝试在
  • Microsoft Interop saveAs 命令失败

    我有一个简单的控制台应用程序 可以使用 Microsoft Office Interop API 将 Word 文档转换为 PDF 由于某种原因 这个文档总是失败 我已将其附加并删除了所有无关的内容 点击这里 由于某种原因 当您打开文档并在
  • 如何使用同一适配器在回收者视图上显示多个模型?

    我有两种不同类型的对象 例如 用户和学生 它们都具有不同的属性 用户 标题描述 学生 标题 描述 USN 有没有一种方法可以使用相同的适配器首先在回收器视图上显示两个用户 然后显示学生 即使它是两个适配器 我如何显示它 我不想要两个回收者视
  • 如何使用 Tycho 构建 zip 文件的功能

    我正在尝试使用 Tycho 导出 Eclipse 功能 替换 Eclipse 功能概述中的 导出向导 该向导提供了将导出目标作为 zip 文件的选项 有没有办法对第谷做同样的事情 为了构建包含该功能和该功能插件的 zip 文件 您需要添加一
  • 如何创建运行时timer.tick事件?

    我真的很烦恼如何在 VB net 上创建一个timer tick 事件 我的程序应该如何工作 实际上 我正在创建一个 FCFS 算法 我的目标是使用进度条显示甘特图 关于这一点 我希望我的计时器能够控制给定的进度条 当进度条达到最大值后 计
  • 如何配置Spring Security以允许在JSP页面中使用hasPermission?

    我正在尝试在我的 spring 项目的 jsp 页面中使用 hasPermission 我已经在我的控制器 服务类的方法中使用它 没有任何问题 阅读文章 http docs spring io spring security site do
  • 复制并粘贴格式,包括单元格颜色 VBA Excel

    wbTarget Sheets Sheet1 Range A1 W79 Value wb Sheets wsSource Name Range A1 W79 Value 我有这段代码 可以将 wb Sheets wsSource Name
  • Ping.SendAsync() 从 0.0.0.0 返回重播,如何获取 ping 地址?

    我对 C 中的 Ping SendAsync 函数有问题 我 ping 一些 IP 地址 但其中一些是错误的 我需要从列表中删除错误的地址 但是如何 因为 p PingCompleted事件参数 replay address is 0 0
  • XSLT 自定义排序

    XSLT 中是否可以按字母顺序排序 其中 5 项为 首选 即给定
  • Python内部如何存储日期时间?

    I found datetimemodule c这似乎是正确的文件 但我需要一些帮助 因为 C 不是我的强项 gt gt gt import datetime gt gt gt import sys gt gt gt d datetime