gpt4 book ai didi

python - __sizeof__ str 大于 __sizeof__ 包含该字符串的元组

转载 作者:太空狗 更新时间:2023-10-30 00:29:14 26 4
gpt4 key购买 nike

以下代码产生给定的输出。

import sys

print('ex1:')
ex1 = 'Hello'
print('\t', ex1.__sizeof__())

print('\nex2:')
ex2 = ('Hello', 53)
print('\t', ex2.__sizeof__())

输出:

ex1:
54
ex2:
40

为什么 __sizeof__() 在考虑第二个元素时打印出较小的结果?输出不是应该更大吗?我从this answer意识到我应该使用 sys.getsizeof(),但这种行为似乎仍然很奇怪。我正在使用 Python 3.5.2

另外,作为 @Herbert指出,'Hello'('Hello',)占用更多内存,后者是一个元组。这是为什么?

最佳答案

这是因为 tuple对象(我很确定除了字符串之外的所有容器)评估它们的大小不是通过包括它们各自内容的实际大小,而是通过计算指向 PyObject 的指针的大小来评估它们的大小。 s 乘以它们包含的元素。也就是说,它们持有指向(通用)PyObject 的指针。它包含在内,这就是影响其整体大小的原因。

Data Model chapter of the Python Reference 中暗示了这一点手册:

Some objects contain references to other objects; these are called containers. Examples of containers are tuples, lists and dictionaries. The references are part of a container’s value.

(我强调的是引用这个词。)

In PyTupleType ,一个结构,其中包含关于 tuple 的信息包含类型,我们看到 tp_itemsize 字段有 sizeof(PyObject *)作为其值(value):

PyTypeObject PyTuple_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"tuple",
sizeof(PyTupleObject) - sizeof(PyObject *),
sizeof(PyObject *), // <-- sizeof pointer to PyObject's

32位构建和 64 Python 的位构建有一个 sizeof(PyObject *)等于 8 个字节。

这是要乘以 tuple 中包含的项目数的值实例。当我们看 object_size , __sizeof__ tuple 的方法s 继承自 object (检查 object.__sizeof__ is tuple.__sizeof__ ),我们清楚地看到:

static PyObject *
object_sizeof(PyObject *self, PyObject *args)
{
Py_ssize_t res, isize;

res = 0;
isize = self->ob_type->tp_itemsize;
if (isize > 0)
res = Py_SIZE(self) * isize; // <-- num_elements * tp_itemsize
res += self->ob_type->tp_basicsize;

return PyLong_FromSsize_t(res);
}

看看如何isize (从 tp_itemsize 获得)乘以 Py_SIZE(self) , 这是另一个获取 ob_size 的宏tuple 中的值表示元素的个数 .

这就是为什么,即使我们在元组实例中创建了一个有点大的字符串:

t = ("Hello" * 2 ** 10,)

其中的元素大小为:

t[0].__sizeof__()         # 5169

元组实例的大小:

t.__sizeof__()            # 32

等于一个简单的 "Hello"里面:

t2 = ("Hello",)
t[0].__sizeof__() # 54
t2.__sizeof__() # 32 Tuple size stays the same.

对于字符串,每个单独的字符都会增加从 str.__sizeof__ 返回的值.这一点,以及 tuple 的事实s 只存储指针,给人一种误导印象 "Hello"比包含它的元组更大。

为了完整性, unicode__sizeof__ 是计算这个的那个。它实际上只是将字符串的长度乘以字符大小(这取决于字符的类型是 124 字节字符)。

我对元组唯一不理解的是为什么它的基本大小(由 tb_basicsize 表示)被列为 sizeof(PyTupleObject) - sizeof(PyObject *) .本棚8返回的总大小中的字节;我还没有找到对此的任何解释。

关于python - __sizeof__ str 大于 __sizeof__ 包含该字符串的元组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40747351/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com