为什么Python中的空字符串有时占据49个字节,有时占据51个字节?

时间:2018-12-22 23:01:24

标签: python

我在三个环境中测试了sys.getsize('')sys.getsize(' '),在其中两个环境中sys.getsize('')给了我51个字节(比第二个多一个字节)而不是49个字节:

屏幕截图:

Win8 + Spyder + CPython 3.6:

sys.getsizeof('') == 49 and sys.getsizeof(' ') == 50

Win8 + Spyder + IPython 3.6:

sys.getsizeof('') == 51 and sys.getsizeof(' ') == 50

Win10(VPN远程)+ PyCharm + CPython 3.7:

sys.getsizeof('') == 51 and sys.getsizeof(' ') == 50

首次编辑

我在Python.exe中做了第二次测试,而不是Spyder和PyCharm(这两个仍然显示51),并且一切似乎都很好。显然,我没有解决此问题的专业知识,所以我会留给你们:)

Win10 + Python 3.7控制台与使用相同解释器的PyCharm:

enter image description here

Win8 + IPython 3.6 + Spyder使用相同的解释器:

enter image description here

2 个答案:

答案 0 :(得分:30)

这听起来像是在检索字符串对象的wchar表示形式。从CPython 3.7开始,CPython Unicode表示的工作方式通常是将空字符串存储在“紧凑ASCII”表示中,并且在64位构建中,紧凑型ASCII字符串的基础数据和填充可计算为48字节,再加上一个字节的字符串数据(只是空终止符)。您可以看到相关的头文件here

目前(4.0中为scheduled for removal),还有一个选项可以检索字符串的wchar_t表示形式。在具有2字节wchar_t的平台上,空字符串的wchar表示形式为2字节(再次只是空终止符)。 wchar表示形式在第一次访问时就缓存在字符串上,str.__sizeof__会在存在额外数据时对其进行处理,从而使总数达到51字节。

答案 1 :(得分:5)

https://docs.python.org/3.5/library/sys.html#sys.getsizeof

sys是特定于系统的,因此可以轻松区别。这通常被每个人忽略。 python中所有系统特定的东西都已经在sys包中倾销了多年。例如,sys.getwindowsversion()根据定义不是可移植的,但它在那里。就像跨平台编码的完美世界中的无底洞。您所看到的是Python有趣的块之一。

来自getsizeof文档:

  

仅考虑直接归因于对象的内存消耗,而不考虑它所引用的对象的内存消耗。   getsizeof()调用对象的__sizeof__方法,如果该对象由垃圾收集器管理,则会添加额外的垃圾收集器开销。

使用垃圾收集时,操作系统将添加这些额外的位。如果您阅读过Python和GC的问答集When are objects garbage collected in python?,那么人们就对GC以及如何影响内存/引用计数和位等问题进行了详尽的阐述。

我希望能解释这是从哪里来的。如果您不使用system级属性,而是使用更多的pythonic属性,那么您将获得一致的大小。