在C中,我们可以找到 int
, char
等的大小 . 我想知道如何在Python中获取对象的大小,如字符串,整数等 .
相关问题:How many bytes per element are there in a Python list (tuple)?
我使用的XML文件包含指定值大小的大小字段 . 我必须解析这个XML并进行编码 . 当我想更改特定字段的值时,我将检查该值的大小字段 . 在这里,我想比较一下我输入的新值是否与XML中的值相同 . 我需要检查新值的大小 . 在字符串的情况下,我可以说它的长度 . 但是在int,float等的情况下我很困惑 .
8 回答
根据您想要计算的内容,这可能比它看起来更复杂 . 例如,如果您有一个整数列表,您是否想要列表的大小包含对int的引用? (即仅列出,而不是包含在其中的内容),或者是否要包含指向的实际数据,在这种情况下,您需要处理重复的引用,以及当两个对象包含对引用的引用时如何防止重复计数同一个对象 .
您可能需要查看其中一个python内存分析器,例如pysizer,看看它们是否满足您的需求 .
这是我根据以前对所有变量列表大小的答案编写的快速脚本
只需使用
sys
模块中定义的sys.getsizeof函数即可 .用法示例,在python 3.0中:
如果您在python <2.6并且没有
sys.getsizeof
,则可以使用this extensive module . 从来没有用过它 .答案是“只使用sys.getsizeof”并不是一个完整的答案 .
该答案直接适用于内置对象,但它不考虑这些对象可能包含的内容,特别是元组,列表,字符串和集合等类型 . 它们可以包含彼此的实例,以及数字,字符串和其他对象 .
更完整的答案
使用来自Anaconda发行版的64位Python 3.6,使用sys.getsizeof,我确定了以下对象的最小大小,并注意set和dicts预分配空间,因此空的不会再次增长,直到设定量(可能因语言的实施而有所不同):
Python 3:
你怎么解释这个?好吧,你有一套10件物品 . 如果每个项目各100个字节,那么整个数据结构有多大?该集合本身就是736,因为它的大小为736字节 . 然后添加项目的大小,总共1736个字节
函数和类定义的一些注意事项:
注意每个类定义对于类attrs具有代理
__dict__
(48字节)结构 . 每个槽在类定义中都有一个描述符(如property
) .Slotted实例在其第一个元素上以48个字节开始,每个额外增加8个 . 只有空的时隙对象有16个字节,而没有数据的实例几乎没有意义 .
此外,每个函数定义都有代码对象,可能是文档字符串,以及其他可能的属性,甚至是
__dict__
.Python 2.7分析,用
guppy.hpy
和sys.getsizeof
确认:请注意,词典(but not sets)在Python 3.6中得到more compact representation
我认为每个附加项目的8个字节在64位机器上很有意义 . 这8个字节指向包含项目所在的内存中的位置 . 如果我没记错的话,4字节是Python 2中unicode的固定宽度,但是在Python 3中,str变成宽度等于字符最大宽度的unicode .
(有关插槽的更多信息,see this answer)
递归访问者以获得更完整的功能
为了覆盖大多数这些类型,我编写了这个递归函数来尝试估计大多数Python对象的大小,包括大多数内置函数,集合模块中的类型和自定义类型(插槽和其他):
而且我很随便地测试它(我应该对它进行单元测试):
它有点打破了类定义和函数定义,因为我没有追求它们的所有属性,但由于它们应该只存在于内存中一次,因此它们的大小确实无关紧要 .
对于numpy数组,
getsizeof
不起作用 - 对我来说它总是因为某些原因返回40:然后(在ipython中):
但幸运的是:
Pympler包的
asizeof
模块可以做到这一点 .使用方法如下:
与
sys.getsizeof
不同,它是 works for your self-created objects . 它甚至适用于numpy .如mentioned,
如果您需要有关实时数据的其他视图,请参阅Pympler's
我自己多次遇到这个问题,我写了一个小函数(灵感来自@ aaron-hall的答案)和测试,它做了我期望的sys.getsizeof做的事情:
https://github.com/bosswissam/pysize
如果你对背景故事感兴趣,here it is
编辑:附上以下代码以便于参考 . 要查看最新代码,请查看github链接 .
第一:答案 .
讨论:
在Python中,您无法访问"direct"内存地址 . 那么,为什么你需要或想要知道给定对象占用了多少这样的地址?它在这个抽象层次上完全不合适 . 当你询问油漆中每个组成原子吸收或反射的光的频率时,你只需询问它是什么颜色 - 产生这种颜色的物理特征的细节就在这一点之外 . 类似地,给定Python对象占用的内存字节数不在此处 .
那么,为什么要尝试使用Python编写C代码? :)