2017-06-05 75 views
1

我的理解是,os.urandom(大小)输出给定的“大小”的字节的随机字符串,但随后:这个字节字符串实际占用多少内存?

import os 
import sys 

print(sys.getsizeof(os.urandom(42))) 

>>> 
75 

这是为什么不是42?

和相关的问题:

import base64 
import binascii 


print(sys.getsizeof(base64.b64encode(os.urandom(42)))) 
print(sys.getsizeof(binascii.hexlify(os.urandom(42)))) 

>>> 
89 
117 

为什么这些如此不同?哪种编码将是存储字节串的最高效内存方式,比如os.urandom给出的字节串?

编辑:这似乎有相当一段时间,说这个问题是What is the difference between len() and sys.getsizeof() methods in python?的重复我的问题不是关于len()和getsizeof()之间的区别。我一般都对Python对象使用的内存感到困惑,这个问题的答案已经为我澄清了。

+0

在第二个例子中,生成的字符串长度不同(base64与hex),因此不相等。你通常可以通过getizeof()的结果并减去每个对象的len()来计算每个对象使用多少内存,因此在你的情况下每个对象都有33个额外的字节添加到它们中。 –

回答

3

Python字节字符串对象不仅仅是构成它们的字符。他们是完全成熟的物体。因此,他们需要更多空间来容纳对象的组件,如方法(split(),isspace(),swapcase()等等)以及所有对象所需的内部基础架构。

最简单的对象,object例如,需要空间:

>>> sys.getsizeof(object()) 
16 

您的问题的第二部分很简单,因为由b64encode()hexlify()产生的串具有不同的长度;后者的长度增加了28个字符,这并不令人意外,这是由sys.getsizeof()报告的值的差异。

>>> 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 

除非你使用某种形式的压缩,没有编码,这将是比你已经拥有的二进制字符串更高效,因为数据是随机时更是如此在这种情况下,这是固有不可压缩的。

相关问题