Python 3中不同的对象大小True和False

在不同的Python对象上试验魔术方法(特别是__sizeof__)我偶然发现了以下行为:

Python 2.7 

>>> False.__sizeof__()
24
>>> True.__sizeof__()
24

Python 3.x 

>>> False.__sizeof__()
24
>>> True.__sizeof__()
28

 在Python 3中改变了什么使True的大小大于False的大小?

 
python
python-3.x
python-2.7
cpython
python-internals
1s

推荐解答

这是因为bool是Python 2和3中int的子类。

>>> issubclass(bool, int)
True

但是int实现已经改变了。 在Python 2中,int是32位或64位的,取决于系统,而不是任意长度的长度。 在Python 3中,int是任意长度的 - Python 2的长度被重命名为int并且原始的Python 2 int完全被删除。

在Python 2中,您可以获得长对象1L和0L完全相同的行为:

Python 2.7.15rc1 (default, Apr 15 2018, 21:51:34) 
[GCC 7.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.getsizeof(1L)
28
>>> sys.getsizeof(0L)
24

long / Python 3 int是一个可变长度的对象,就像一个元组 - 当它被分配时,分配了足够的内存来保存表示它所需的所有二进制数字。 可变部分的长度存储在对象头中。 0不需要二进制数字(其可变长度为0),但即使1溢出,也需要额外的数字。

0表示为长度为0的二进制字符串:

<>

1表示为30位二进制字符串:

<000000000000000000000000000001>

Python中的默认配置在uint32_t中使用30位; 所以2 ** 30 - 1仍然适合x86-64的28字节,而2 ** 30则需要32;

2 ** 30 - 1将显示为:

<111111111111111111111111111111>

所有30个值位设置为1; 2 ** 30将需要更多,它将具有内部表示:

<000000000000000000000000000001000000000000000000000000000000>

至于True使用28个字节而不是24个 - 你不必担心。 True是一个单例,因此在任何Python程序中总共只丢失4个字节,而对于每次使用True都不会丢失4个字节。

  nopapp推荐