sys.getsizeof
返回标准字符串的内容是什么?我注意到这个值远高于len
返回的值。
答案 0 :(得分:3)
我会尝试从更广泛的角度回答你的问题。你指的是两个函数并比较它们的输出。我们先来看看他们的文档:
返回对象的长度(项目数)。争论可能 是一个序列(如字符串,字节,元组,列表或范围)或a 集合(例如字典,集合或冻结集)。
因此,如果是字符串,您可以期望len()
返回字符数。
以字节为单位返回对象的大小。对象可以是任何类型的 宾语。所有内置对象都将返回正确的结果,但这样 并不一定适用于第三方扩展 具体实施。
因此,对于字符串(与许多其他对象一样),您可以期望sys.getsizeof()
对象的大小(以字节为单位)。没有理由认为它应该与字符数相同。
让我们看看一些例子:
>>> first = "First"
>>> len(first)
5
>>> sys.getsizeof(first)
42
此示例确认大小与字符数不同。
>>> second = "Second"
>>> len(second)
6
>>> sys.getsizeof(second)
43
我们可以注意到,如果我们看一个字符串长一个字符,它的大小也会增加一个字节。但我们不知道这是不是巧合。
>>> together = first + second
>>> print(together)
FirstSecond
>>> len(together)
11
如果我们连接两个字符串,它们的组合长度等于它们的长度之和,这是有道理的。
>>> sys.getsizeof(together)
48
与人们可能期望的相反,组合字符串的大小不等于其各自大小的总和。但它似乎仍然是长度加上某事。特别是,某事值37个字节。现在你需要意识到在这种特殊情况下它是37个字节,使用这个特定的Python实现等。你根本不应该依赖它。不过,我们可以看看为什么它们(大约)用于37个字节。
String对象位于CPython(可能是最广泛使用的Python实现)中,实现为PyStringObject
。这是C source code(我使用2.7.9版本):
typedef struct {
PyObject_VAR_HEAD
long ob_shash;
int ob_sstate;
char ob_sval[1];
/* Invariants:
* ob_sval contains space for 'ob_size+1' elements.
* ob_sval[ob_size] == 0.
* ob_shash is the hash of the string or -1 if not computed yet.
* ob_sstate != 0 iff the string object is in stringobject.c's
* 'interned' dictionary; in this case the two references
* from 'interned' to this object are *not counted* in ob_refcnt.
*/
} PyStringObject;
您可以看到有一个名为PyObject_VAR_HEAD
,一个int
,一个long
和一个char
数组的内容。 char数组将始终包含一个字符,用于将'\0'
存储在字符串的末尾。这与int
,long
和PyObject_VAR_HEAD
一起使用额外的37个字节。 PyObject_VAR_HEAD
中定义了sys.getsizeof()
,它引用了其他特定于实现的内容,您需要探索是否要查找37个字节的确切位置。另外,another C source file提及Typeface
如果管理对象,会增加额外的垃圾收集器开销 由垃圾收集器。
总的来说,你不需要知道某些东西究竟是什么(这里是37个字节),但是这个答案应该让你知道为什么数字不同以及在哪里可以找到更多信息你真的需要它。
答案 1 :(得分:2)
引用文档:
以字节为单位返回对象的大小。对象可以是任何类型的对象。所有内置对象都将返回正确的结果,但这不一定适用于第三方扩展,因为它是特定于实现的。
内置字符串不是简单的字符序列 - 它们是完全成熟的对象,具有垃圾收集开销,这可能解释了您注意到的大小差异。