如何确定Python中对象的大小?

如何确定Python中对象的大小?

在C中,我们可以找到intchar等等,我想知道如何在Python中获取对象的大小,比如字符串、整数等等。

有关问题:Python列表(Tuple)中每个元素有多少字节?

我正在使用一个XML文件,其中包含指定值大小的大小字段。我必须解析这个XML并进行编码。当我想更改特定字段的值时,我将检查该值的大小字段。在这里,我想比较一下我要输入的新值是否与XML中的相同大小。我需要检查新价值的大小。如果是字符串,我可以说是长度。但是如果是整数,浮动等,我很困惑。


慕斯709654
浏览 2521回答 3
3回答

人到中年有点甜

只需使用sys.getsize中定义的函数。sys模块。sys.getsizeof(object[, default]):返回对象的大小(以字节为单位)。对象可以是任何类型的对象。所有内置对象都将返回正确的结果,但对于第三方扩展来说,这并不一定成立,因为它是特定于实现的。这个default参数允许定义一个值,如果对象类型不提供检索大小的方法并将导致TypeError.getsizeof调用对象的__sizeof__方法,如果对象由垃圾收集器管理,则添加额外的垃圾回收器开销。使用示例,在python3.0中:>>>&nbsp;import&nbsp;sys>>>&nbsp;x&nbsp;=&nbsp;2>>>&nbsp;sys.getsizeof(x)24>>>&nbsp;sys.getsizeof(sys.getsizeof)32>>>&nbsp;sys.getsizeof('this')38>>>&nbsp;sys.getsizeof('this&nbsp;also')48如果您在python<2.6并且没有sys.getsizeof你可以用这个广泛的模块相反。但从没用过。

慕姐8265434

如何确定Python中对象的大小?答案是,“只使用sys.getsize of”不是一个完整的答案。这个答案是吗?直接为内置对象工作,但它不考虑这些对象可能包含哪些类型,特别是自定义对象、元组、列表、数据集和集合包含的类型。它们可以包含彼此的实例,以及数字、字符串和其他对象。更完整的答案使用Anaconda发行版中的64位Pythonda版本中的64位Python 3.6和sys.getsize of,我确定了以下对象的最小大小,并注意到SET和DECT预先分配了空间,这样空间才会在设置数量之后才会再次增长(这可能随着语言的实现而不同):Python 3:Empty Bytes&nbsp;&nbsp;type&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scaling&nbsp;notes 28&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+4&nbsp;bytes&nbsp;about&nbsp;every&nbsp;30&nbsp;powers&nbsp;of&nbsp;2 37&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bytes&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+1&nbsp;byte&nbsp;per&nbsp;additional&nbsp;byte 49&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+1-4&nbsp;per&nbsp;additional&nbsp;character&nbsp;(depending&nbsp;on&nbsp;max&nbsp;width) 48&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tuple&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+8&nbsp;per&nbsp;additional&nbsp;item 64&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+8&nbsp;for&nbsp;each&nbsp;additional 224&nbsp;&nbsp;&nbsp;&nbsp;set&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5th&nbsp;increases&nbsp;to&nbsp;736;&nbsp;21nd,&nbsp;2272;&nbsp;85th,&nbsp;8416;&nbsp;341,&nbsp;32992 240&nbsp;&nbsp;&nbsp;&nbsp;dict&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;6th&nbsp;increases&nbsp;to&nbsp;368;&nbsp;22nd,&nbsp;1184;&nbsp;43rd,&nbsp;2280;&nbsp;86th,&nbsp;4704;&nbsp;171st,&nbsp;9320 136&nbsp;&nbsp;&nbsp;&nbsp;func&nbsp;def&nbsp;&nbsp;&nbsp;&nbsp;does&nbsp;not&nbsp;include&nbsp;default&nbsp;args&nbsp;and&nbsp;other&nbsp;attrs 1056&nbsp;&nbsp;&nbsp;class&nbsp;def&nbsp;&nbsp;&nbsp;no&nbsp;slots&nbsp; 56&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;inst&nbsp;&nbsp;has&nbsp;a&nbsp;__dict__&nbsp;attr,&nbsp;same&nbsp;scaling&nbsp;as&nbsp;dict&nbsp;above 888&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;def&nbsp;&nbsp;&nbsp;with&nbsp;slots 16&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__slots__&nbsp;&nbsp;&nbsp;seems&nbsp;to&nbsp;store&nbsp;in&nbsp;mutable&nbsp;tuple-like&nbsp;structure &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;first&nbsp;slot&nbsp;grows&nbsp;to&nbsp;48,&nbsp;and&nbsp;so&nbsp;on.你怎么解释这个?好吧,假设你有一套,里面有10件物品。如果每个项目都是100个字节,那么整个数据结构有多大?集合本身是736个,因为它将大小调整到736字节。然后,将项目的大小相加,总共为1736字节。函数和类定义的一些注意事项:注每个类定义都有一个代理。__dict__(48字节)类的结构。每个插槽都有一个描述符(类似于property)在类定义中。时隙实例从其第一个元素上的48个字节开始,每增加8个字节。只有空时隙对象有16个字节,没有数据的实例没有什么意义。而且,每个函数定义都有代码对象,可能是docstring和其他可能的属性,甚至是__dict__.Python 2.7分析,与guppy.hpy和sys.getsizeof:Bytes&nbsp;&nbsp;type&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;empty&nbsp;+&nbsp;scaling&nbsp;notes 24&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NA 28&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;long&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NA 37&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+&nbsp;1&nbsp;byte&nbsp;per&nbsp;additional&nbsp;character 52&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unicode&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+&nbsp;4&nbsp;bytes&nbsp;per&nbsp;additional&nbsp;character 56&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tuple&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+&nbsp;8&nbsp;bytes&nbsp;per&nbsp;additional&nbsp;item 72&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+&nbsp;32&nbsp;for&nbsp;first,&nbsp;8&nbsp;for&nbsp;each&nbsp;additional 232&nbsp;&nbsp;&nbsp;&nbsp;set&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sixth&nbsp;item&nbsp;increases&nbsp;to&nbsp;744;&nbsp;22nd,&nbsp;2280;&nbsp;86th,&nbsp;8424 280&nbsp;&nbsp;&nbsp;&nbsp;dict&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sixth&nbsp;item&nbsp;increases&nbsp;to&nbsp;1048;&nbsp;22nd,&nbsp;3352;&nbsp;86th,&nbsp;12568&nbsp;* 120&nbsp;&nbsp;&nbsp;&nbsp;func&nbsp;def&nbsp;&nbsp;&nbsp;&nbsp;does&nbsp;not&nbsp;include&nbsp;default&nbsp;args&nbsp;and&nbsp;other&nbsp;attrs 64&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;inst&nbsp;&nbsp;has&nbsp;a&nbsp;__dict__&nbsp;attr,&nbsp;same&nbsp;scaling&nbsp;as&nbsp;dict&nbsp;above 16&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__slots__&nbsp;&nbsp;&nbsp;class&nbsp;with&nbsp;slots&nbsp;has&nbsp;no&nbsp;dict,&nbsp;seems&nbsp;to&nbsp;store&nbsp;in&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mutable&nbsp;tuple-like&nbsp;structure. 904&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;def&nbsp;&nbsp;&nbsp;has&nbsp;a&nbsp;proxy&nbsp;__dict__&nbsp;structure&nbsp;for&nbsp;class&nbsp;attrs 104&nbsp;&nbsp;&nbsp;&nbsp;old&nbsp;class&nbsp;&nbsp;&nbsp;makes&nbsp;sense,&nbsp;less&nbsp;stuff,&nbsp;has&nbsp;real&nbsp;dict&nbsp;though.请注意字典(但没有设定)有更紧表示在Python3.6中我认为,在64位机器上,每增加一个项目引用8个字节是很有意义的。这8个字节指向内存中包含的项所在的位置。如果我没记错的话,Python 2中的Unicode的4个字节是固定的宽度,但是在Python 3中,str变成了宽度等于字符最大宽度的Unicode。(至于更多的插槽,见这个答案&nbsp;)更完整的函数我们需要一个函数来搜索列表、元组、集合、切分中的元素,obj.__dict__和obj.__slots__以及其他我们可能还没有想到的事情。我们想依靠gc.get_referents执行此搜索,因为它在C级别工作(使其非常快)。缺点是GET_Referents可以返回冗余成员,因此我们需要确保不进行双重计数。类、模块和函数是单个的-它们在内存中存在过一次。我们对它们的大小不太感兴趣,因为我们对它们无能为力-它们是项目的一部分。因此,如果它们碰巧被引用,我们将避免计算它们。我们将使用黑名单的类型,所以我们不包括整个程序在我们的大小计数。import&nbsp;sysfrom&nbsp;types&nbsp;import&nbsp;ModuleType,&nbsp;FunctionTypefrom&nbsp;gc&nbsp;import&nbsp;get_referents#&nbsp;Custom&nbsp;objects&nbsp;know&nbsp;their&nbsp;class.#&nbsp;Function&nbsp;objects&nbsp;seem&nbsp;to &nbsp;know&nbsp;way&nbsp;too&nbsp;much,&nbsp;including&nbsp;modules.#&nbsp;Exclude&nbsp;modules&nbsp;as&nbsp;well.BLACKLIST&nbsp;=&nbsp;type,&nbsp;ModuleType,&nbsp;FunctionTypedef&nbsp;getsize(obj): &nbsp;&nbsp;&nbsp;&nbsp;"""sum&nbsp;size&nbsp;of&nbsp;object&nbsp;&&nbsp;members.""" &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;isinstance(obj,&nbsp;BLACKLIST): &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise&nbsp;TypeError('getsize()&nbsp;does&nbsp;not&nbsp;take&nbsp;argument&nbsp;of&nbsp;type:&nbsp;'+&nbsp;str(type(obj))) &nbsp;&nbsp;&nbsp;&nbsp;seen_ids&nbsp;=&nbsp;set() &nbsp;&nbsp;&nbsp;&nbsp;size&nbsp;=&nbsp;0 &nbsp;&nbsp;&nbsp;&nbsp;objects&nbsp;=&nbsp;[obj] &nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;objects: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;need_referents&nbsp;=&nbsp;[] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;obj&nbsp;in&nbsp;objects: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;not&nbsp;isinstance(obj,&nbsp;BLACKLIST)&nbsp;and&nbsp;id(obj)&nbsp;not&nbsp;in&nbsp;seen_ids: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;seen_ids.add(id(obj)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;size&nbsp;+=&nbsp;sys.getsizeof(obj) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;need_referents.append(obj) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;objects&nbsp;=&nbsp;get_referents(*need_referents) &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;size与以下白名单中的函数相比,大多数对象都知道如何为垃圾收集的目的遍历自己(当我们想知道某些对象在内存中的开销时,这几乎就是我们要寻找的。使用此功能的gc.get_referents)然而,如果我们不小心,这项措施的范围将比我们打算的要大得多。例如,函数非常了解在其中创建的模块。另一个对比点是,作为字典中键的字符串通常是内嵌的,因此它们不会被复制。检查id(key)也将允许我们避免计算重复数,这是我们在下一节中所做的。黑名单解决方案跳过计算字符串的键。白色类型,递归访问者(旧实现)为了自己涵盖这些类型中的大多数,我编写了这个递归函数,而不是依赖于GC模块,以尝试估计大多数Python对象的大小,包括大多数内置器、集合模块中的类型和自定义类型(时隙和其他类型)。这类函数对我们将要计算的内存使用类型提供了更细粒度的控制,但有将类型排除在外的危险:import&nbsp;sysfrom&nbsp;numbers&nbsp;import&nbsp;Numberfrom&nbsp;collections&nbsp;import&nbsp;Set,&nbsp;Mapping,&nbsp;dequetry:&nbsp;#&nbsp;Python&nbsp;2 &nbsp;&nbsp;&nbsp;&nbsp;zero_depth_bases&nbsp;=&nbsp;(basestring,&nbsp;Number,&nbsp;xrange,&nbsp;bytearray) &nbsp;&nbsp;&nbsp;&nbsp;iteritems&nbsp;=&nbsp;'iteritems'except&nbsp;NameError:&nbsp;#&nbsp;Python&nbsp;3 &nbsp;&nbsp;&nbsp;&nbsp;zero_depth_bases&nbsp;=&nbsp;(str,&nbsp;bytes,&nbsp;Number,&nbsp;range,&nbsp;bytearray) &nbsp;&nbsp;&nbsp;&nbsp;iteritems&nbsp;=&nbsp;'items'def&nbsp;getsize(obj_0): &nbsp;&nbsp;&nbsp;&nbsp;"""Recursively&nbsp;iterate&nbsp;to&nbsp;sum&nbsp;size&nbsp;of&nbsp;object&nbsp;&&nbsp;members.""" &nbsp;&nbsp;&nbsp;&nbsp;_seen_ids&nbsp;=&nbsp;set() &nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;inner(obj): &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;obj_id&nbsp;=&nbsp;id(obj) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;obj_id&nbsp;in&nbsp;_seen_ids: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;0 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_seen_ids.add(obj_id) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;size&nbsp;=&nbsp;sys.getsizeof(obj) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;isinstance(obj,&nbsp;zero_depth_bases): &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pass&nbsp;#&nbsp;bypass&nbsp;remaining&nbsp;control&nbsp;flow&nbsp;and&nbsp;return &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;elif&nbsp;isinstance(obj,&nbsp;(tuple,&nbsp;list,&nbsp;Set,&nbsp;deque)): &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;size&nbsp;+=&nbsp;sum(inner(i)&nbsp;for&nbsp;i&nbsp;in&nbsp;obj) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;elif&nbsp;isinstance(obj,&nbsp;Mapping)&nbsp;or&nbsp;hasattr(obj,&nbsp;iteritems): &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;size&nbsp;+=&nbsp;sum(inner(k)&nbsp;+&nbsp;inner(v)&nbsp;for&nbsp;k,&nbsp;v&nbsp;in&nbsp;getattr(obj,&nbsp;iteritems)()) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;Check&nbsp;for&nbsp;custom&nbsp;object&nbsp;instances&nbsp;-&nbsp;may&nbsp;subclass&nbsp;above&nbsp;too &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;hasattr(obj,&nbsp;'__dict__'): &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;size&nbsp;+=&nbsp;inner(vars(obj)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;hasattr(obj,&nbsp;'__slots__'):&nbsp;#&nbsp;can&nbsp;have&nbsp;__slots__&nbsp;with&nbsp;__dict__ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;size&nbsp;+=&nbsp;sum(inner(getattr(obj,&nbsp;s))&nbsp;for&nbsp;s&nbsp;in&nbsp;obj.__slots__&nbsp;if&nbsp;hasattr(obj,&nbsp;s)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;size&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;inner(obj_0)我对它的测试相当随意(我应该对它进行单元测试):>>>&nbsp;getsize(['a',&nbsp;tuple('bcd'),&nbsp;Foo()])344>>>&nbsp;getsize(Foo())16>>>&nbsp;getsize(tuple('bcd'))194>>>&nbsp;getsize(['a',&nbsp;tuple('bcd'),&nbsp;Foo(),&nbsp;{'foo':&nbsp; 'bar',&nbsp;'baz':&nbsp;'bar'}])752>>>&nbsp;getsize({'foo':&nbsp;'bar',&nbsp;'baz':&nbsp;'bar'})400>>>&nbsp;getsize({})280>>>&nbsp;getsize({'foo':'bar'})360>>>&nbsp;getsize('foo')40>>> &nbsp;class&nbsp;Bar():...&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;baz():...&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pass>>>&nbsp;getsize(Bar())352>>>&nbsp;getsize(Bar().__dict__)280>>>&nbsp;sys.getsizeof(Bar())72>>>&nbsp;getsi &nbsp;ze(Bar.__dict__)872>>>&nbsp;sys.getsizeof(Bar.__dict__)280这个实现对类定义和函数定义进行了分解,因为我们并不追求它们的所有属性,但是由于它们应该只在进程的内存中存在一次,所以它们的大小并不重要。

拉丁的传说

对于Numpy数组,getsizeof不管用-对我来说,它总是因为某种原因而返回40:from&nbsp;pylab&nbsp;import&nbsp;*from&nbsp;sys&nbsp;import&nbsp;getsizeof A&nbsp;=&nbsp;rand(10)B&nbsp;=&nbsp;rand(10000)然后(在IPython中):In&nbsp;[64]:&nbsp;getsizeof(A)Out[64]:&nbsp;40In&nbsp;[65]:&nbsp;getsizeof(B)Out[65]:&nbsp;40不过,令人高兴的是:In&nbsp;[66]:&nbsp;A.nbytesOut[66]:&nbsp;80In&nbsp;[67]:&nbsp;B.nbytesOut[67]:&nbsp;80000
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python