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

为什么Python中的空字符串有时占49字节,有时占51字节?,python,Python,我在三个环境中测试了sys.getsize(“”)和sys.getsize(“”),其中两个环境中sys.getsize(“”)给了我51个字节(比第二个多一个字节),而不是49个字节: 截图: Win8+Spyder+CPython 3.6: Win8+Spyder+IPython 3.6: Win10(VPN远程)+PyCharm+CPython 3.7: 第一次编辑 我在Python.exe中做了第二次测试,而不是Spyder和PyCharm(这两个仍然显示为51),一切似乎都很好。

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

截图:

Win8+Spyder+CPython 3.6:

Win8+Spyder+IPython 3.6:

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

第一次编辑

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

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

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

sys
是特定于系统的,因此很容易区分。这一点往往被所有人忽视。python中所有特定于系统的东西多年来都被转储在
sys
包中。例如,
sys.getwindowsversion()
根据定义是不可移植的,但它确实存在。它就像是在跨平台编码的完美世界中的无底洞。您看到的是Python的一个有趣的金块

getsizeof
文档:

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

当使用垃圾收集时,操作系统将添加这些额外的位。如果你阅读Python和GC Q&A,人们已经进入了令人痛苦的细节,阐述了GC以及它将如何影响内存/引用计数和位等等


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

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


目前(在4.0中),还有一个选项可以检索字符串的wchar\t表示形式。在具有2字节wchar__t的平台上,空字符串的wchar表示为2字节(再次仅为空终止符)。wchar表示在第一次访问时缓存在字符串上,并且
str.\uuuuu sizeof\uuuuu
会在该额外数据存在时对其进行解释,从而产生51字节的总数。

我最迫切的问题是“它为什么重要?”。但不管怎样,Spyder也会将其投入到一个共享系统中namespace@roganjosh事实上,我认为这并不重要,因为我作为一名数据分析师的工作并不要求我深入研究对象模型,但我正在挠头去理解这背后的原因。我希望我有其他操作系统,例如Linux来测试这个。顺便问一下,这和你说的“共享名称空间”有关系吗?我的工作也是数据科学家/数据分析师。这种行为无关紧要,但我不想让你的问题无效(好奇心没问题)。Spyder有一个复杂的名称空间,你一定已经从你的主脚本中观察到了控制台中的东西是如何可用的…@Andreytukin不,我只是想看看以前是否有人遇到过这种奇怪的事情,更重要的是,如果一个空字符串比一个带一个字符的字符串多1个字节,这意味着我对字符串对象的理解可能是完全错误的。如果你认为这是正常的,那么对不起,因为我不是专业的软件开发人员,这对我来说确实很奇怪。现在我已经解决了这个问题,Python.exe控制台的第二个测试显示了49。最有可能的候选者似乎是字符串在第一次需要时缓存了一个用UTF-8编码的版本。它不是GC数据。GC从不跟踪字符串对象;他们没有这些数据。同样,同样的对象会有关于提问者测试的所有配置的GC数据。然后我会被纠正。它可能不是GC。然而,代表性的差异仍然适用,并且是系统特定的。它可能是OS+运行时getsizeof()在内部引用的是
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
。这是正确的答案谢谢!虽然我没有得到完整的图片,这似乎可以解释51字节的来源。只是好奇,为什么Spyder和CPython在同一台PC上给我49字节,而给IPython显示51字节?我从你的回答中得出结论,这与wchar的大小有关,反过来ide会得到2个字节,因为它是由操作系统指定的,但我认为对所有解释器来说应该是相同的?无论如何,我可能误解了你的答案…@NicholasHumphrey:有东西在你的IPython测试中检索wchar表示。(另外,您的IPython测试也在使用CPython;CPython是IPython运行的解释器实现。)这与问题基本无关,但看到对“[Python]4.0”的引用让我感到焦虑…@MikeCaron和其他人:不要害怕。对“4.0”的引用意味着“2.7支持结束后(2020年1月)的某些未来版本”。一些弃用后的删除被延迟,以使那些喜欢较小步骤的人更容易迁移。大约6年前,3.3中不推荐的东西可能在3.5中消失了。我们不再允许新引用虚构的“4.0”。我只是建议,我们将这项政策“后推”到旧的通知上,恰恰是为了避免没有人需要的“焦虑”。