Python如何在内部存储datetime?
我发现这似乎是正确的文件,但我需要一些帮助,因为C不是我的强项Python如何在内部存储datetime?,python,c,datetime,memory,cpython,Python,C,Datetime,Memory,Cpython,我发现这似乎是正确的文件,但我需要一些帮助,因为C不是我的强项 >>> import datetime >>> import sys >>> d = datetime.datetime.now() >>> sys.getsizeof(d) 48 >>> d = datetime.datetime(2018, 12, 31, 23, 59, 59, 123) >>> sys.getsizeo
>>> 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
因此,一个不知道时区的datetime对象需要48字节。查看PyDateTime\u-DateTimeType
,它似乎是PyDateTime\u-DateType
和PyDateTime\u-TimeType
。也可以\u PyDateTime\u BaseTime
通过查看代码,我的印象是,在YYYY-mm-dd HH:mm:ss
中,每个字段都存储了一个组件,这意味着:
- 年份:例如int(例如
将为16位)int16\t
- 月份:例如
int8\u t
- 日期:例如
int8\t
- 小时:例如
int8\u t
- 分钟:例如
int8\u t
- 第二:例如
int8\u t
- 微秒:例如
uint16\u t
(我想这可能在Python实现之间有所不同——如果是这样,请关注cPython)您缺少了一个关键部分:实际的datetime结构定义,它位于。这里也有重要的评论。以下是一些关键摘录:
/*字段被压缩成连续的字节,每个字节都被视为无符号和
*big-endian,除非另有说明:
*
*字节偏移量
*0年2字节,1-9999
*2个月1字节,1-12
*3天1字节,1-31
*4小时1字节,0-23
*5分钟1字节,0-59
*6秒1字节,0-59
*7秒3字节,0-999999
* 10
*/
...
/*年、月、日、时、分、秒和秒的字节数*/
#定义_PyDateTime_DATETIME_DATASIZE 10
...
/*datetime和time类型具有哈希代码和可选的tzinfo成员,
*当且仅当hastzinfo为true时显示。
*/
#定义_PyTZINFO_HEAD\
皮尤头\
Py_hash_t hashcode\
char hastzinfo;/*布尔标志*/
...
/*所有datetime对象都是PyDateTime\u DateTimeType,但可以是
*也有两种分配方式,就像上面的时间对象一样。此外
*普通日期类型是datetime的基类,因此它还必须具有
*hastzinfo成员(尽管它在那里未使用)。
*/
...
#定义_PyDateTime_DATETIMEHEAD\
_皮兹乌头\
无符号字符数据[_PyDateTime_DATETIME_DATASIZE];
类型定义结构
{
_PyDateTime\u日期时间头
}_PyDateTime_BaseDateTime;/*hastzinfo错误*/
类型定义结构
{
_PyDateTime\u日期时间头
无符号字符折叠;
PyObject*tzinfo;
}PyDateTime_DateTime;/*hastzinfo-true*/
您看到的48字节计数分解如下:
- 8字节引用计数
- 8字节型指针
- 8字节缓存哈希
- 1字节“hastzinfo”标志
- 7字节填充
- 包含日期时间数据的10字节手动压缩
char[10]
- 6字节填充
当然,这是所有实现细节。在不同的Python实现、不同的CPython版本、32位CPython构建或CPython调试构建(当CPython使用定义的Py_跟踪_引用编译时,PyObject_头中有额外的内容)上可能会有所不同。请注意
打印(sys.getsizeof(d.year));打印(sys.getsizeof(d.month));打印(sys.getsizeof(d.day));打印(sys.getsizeof(d.hour));打印(sys.getsizeof(d.minute));打印(sys.getsizeof(d.second));打印(sys.getsizeof(d.microsecond))
打印28
七次,并且28*7
是196
请注意,您正在计算位(2 int16 ts=2*16)而不是字节(int16 t=2字节)。字节,这是10字节。但是python对象有开销,最小大小似乎至少为28字节,有时更大,具体取决于对象。不过我没有做过那么多的调查。usecond:3字节
可能是打字错误吗?哪种类型有3个字节?我只看到一些是2字节的,一些是4字节的。@MartinThoma:datetime数据的字节是手动打包在char[10]
中的,因此不需要3字节类型。