How much memory does this byte string actually take up?
我的理解是os.urandom(size)输出一个给定"size"的随机字节串,但是:
1 2 3 4 5 6 7 | import os import sys print(sys.getsizeof(os.urandom(42))) >>> 75 |
为什么这不是42?
以及一个相关问题:
1 2 3 4 5 6 7 8 9 10 | import base64 import binascii print(sys.getsizeof(base64.b64encode(os.urandom(42)))) print(sys.getsizeof(binascii.hexlify(os.urandom(42)))) >>> 89 117 |
号
为什么它们如此不同?哪种编码方式是存储字符串字节(如os.urandom给出的字节)最有效的内存方式?
编辑:如果说这个问题是Python中len()和sys.getsizeof()方法之间的区别的一个副本,那么这似乎是一个很大的问题。我的问题不是关于len()和getsizeof()之间的区别。我对Python对象通常使用的内存感到困惑,这个问题的答案已经为我澄清了。
python字节字符串对象不仅仅是组成它们的字符。它们是羽翼丰满的物体。因此,它们需要更多的空间来容纳对象的组件,例如类型指针(需要识别字节串是什么类型的对象)和长度(需要提高效率,因为python字节串可以包含空字节)。
最简单的对象,
1 2 | >>> sys.getsizeof(object()) 16 |
问题的第二部分只是因为
1 2 3 4 5 6 7 8 9 10 11 | >>> s1 = base64.b64encode(os.urandom(42)) >>> s1 b'CtlMjDM9q7zp+pGogQci8gr0igJsyZVjSP4oWmMj2A8diawJctV/8sTa' >>> s2 = binascii.hexlify(os.urandom(42)) >>> s2 b'c82d35f717507d6f5ffc5eda1ee1bfd50a62689c08ba12055a5c39f95b93292ddf4544751fbc79564345' >>> len(s2) - len(s1) 28 >>> sys.getsizeof(s2) - sys.getsizeof(s1) 28 |
号
除非使用某种形式的压缩,否则没有比现有的二进制字符串更有效的编码,在这种情况下尤其如此,因为数据是随机的,这是固有的不可压缩的。