我将尝试从更广泛的角度回答您的问题。您指的是两个函数并比较它们的输出。我们先来看看他们的文档:
返回对象的长度(项目数)。参数可以是序列(例如字符串、字节、元组、列表或范围)或集合(例如字典、集合或冻结集合)。
因此,对于字符串,您可以期望len()返回字符数。
以字节为单位返回对象的大小。对象可以是任何类型的对象。所有内置对象都将返回正确的结果,但对于第三方扩展,这不一定适用,因为它是特定于实现的。
因此,对于字符串(与许多其他对象一样),您可以预期sys.getsizeof()对象的大小(以字节为单位)。没有理由认为它应该与字符数相同。
让我们看一些例子:
>>> first = "First"
>>> len(first)
5
>>> sys.getsizeof(first)
42
Run Code Online (Sandbox Code Playgroud)
此示例确认大小与字符数不同。
>>> second = "Second"
>>> len(second)
6
>>> sys.getsizeof(second)
43
Run Code Online (Sandbox Code Playgroud)
我们可以注意到,如果我们查看一个字符串长一个字符,它的大小也大一个字节。我们不知道这是否是巧合。
>>> together = first + second
>>> print(together)
FirstSecond
>>> len(together)
11
Run Code Online (Sandbox Code Playgroud)
如果我们连接两个字符串,它们的组合长度等于它们的长度之和,这是有道理的。
>>> sys.getsizeof(together)
48
Run Code Online (Sandbox Code Playgroud)
然而,与某些人可能期望的相反,组合字符串的大小不等于它们各自大小的总和。不过好像还是长度加了点什么。特别是,价值 37 字节的东西。现在你需要意识到在这个特殊情况下它是 37 个字节,使用这个特殊的 Python 实现等。你根本不应该依赖它。不过,我们可以看看为什么它们(大约)用于 37 个字节。
字符串对象在 CPython(可能是最广泛使用的 Python 实现)中实现为PyStringObject. 这是C源代码(我使用的是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;
Run Code Online (Sandbox Code Playgroud)
你可以看到有一个叫做PyObject_VAR_HEAD, one int, onelong和一个char数组的东西。char 数组将始终包含一个多字符以存储'\0'在字符串的末尾。此,伴随着int,long并PyObject_VAR_HEAD利用额外的37个字节。PyObject_VAR_HEAD在另一个 C 源文件中定义,它指的是其他特定于实现的东西,如果你想找出 37 个字节的确切位置,你需要探索。另外,文档提到sys.getsizeof()
如果对象由垃圾收集器管理,则会增加额外的垃圾收集器开销。
总体而言,您不需要知道究竟是什么需要某些东西(此处为 37 个字节),但是这个答案应该可以让您了解为什么数字不同,以及如果您真的需要它,可以在哪里找到更多信息。