object text用法 - 我如何確定Python中對象的大小?




matplotlib文字 python用法 (9)

Pympler軟件包的asizeof模塊可以做到這一點。

使用方法如下:

from pympler import asizeof
asizeof.asizeof(my_object)

不像sys.getsizeof ,它適用於你自己創建的對象 。 它甚至適用於numpy。

>>> asizeof.asizeof(tuple('bcd'))
200
>>> asizeof.asizeof({'foo': 'bar', 'baz': 'bar'})
400
>>> asizeof.asizeof({})
280
>>> asizeof.asizeof({'foo':'bar'})
360
>>> asizeof.asizeof('foo')
40
>>> asizeof.asizeof(Bar())
352
>>> asizeof.asizeof(Bar().__dict__)
280
>>> A = rand(10)
>>> B = rand(10000)
>>> asizeof.asizeof(A)
176
>>> asizeof.asizeof(B)
80096

mentioned

通過設置選項code=True ,可以包括諸如類,函數,方法,模塊等對象的(字節)代碼大小。

如果您需要關於實時數據的其他觀點,Pympler的

module muppy用於在線監控Python應用程序和模塊Class Tracker提供離線分析選定Python對象的生命週期。

在C中,我們可以找到intchar等的大小。我想知道如何在Python中獲取像字符串,整數等對象的大小。

相關問題: Python列表(元組)中每個元素有多少個字節?

我正在使用包含指定值大小的大小字段的XML文件。 我必須解析這個XML並進行編碼。 當我想要更改特定字段的值時,我將檢查該值的大小字段。 在這裡我想比較一下我輸入的新值是否與XML中的大小相同。 我需要檢查新值的大小。 如果是字符串,我可以說它的長度。 但在int,float等情況下,我很困惑。


這可能比看起來更複雜,取決於你想如何計算東西。 例如,如果您有一個整數列表,您是否希望列表的大小包含對整數的引用 ? (即僅列表,而不是其中包含的內容),還是希望包含指向的實際數據,在這種情況下,您需要處理重複引用,以及如何防止在兩個對象包含引用時重複計算同一個對象。

您可能需要查看一下python內存分析器,比如pysizer ,看看它們是否滿足您的需求。


首先:答案。

import sys

try: print sys.getsizeof(object)
except AttributeError:
    print "sys.getsizeof exists in Python ≥2.6"

討論:
在Python中,你永遠不能訪問“直接”內存地址。 那麼,為什麼你需要或想知道給定對象佔用了多少這樣的地址? 這是一個在抽象層面完全不合適的問題。 當你在繪畫你的房子時,你不會問什麼頻率的光被油漆中的每個組成原子吸收或反射,你只要問它是什麼顏色 - 創建該顏色的物理特徵的細節在旁邊。 同樣,給定的Python對象所佔用的內存字節數量也是非常重要的。

那麼,你為什麼試圖用Python來編寫C代碼呢? :)


如果有人遇到這個問題,需要比sys.getsizeof或Aaron Hall提供的程序更“防彈”的解決方案,這裡有一個配方,試圖以原則和靈活的方式處理類和字節碼對像等問題(不幸的是,複製或有意義地總結這段時間太長了)。


下面是我根據之前對所有變量列表大小的回答編寫的一個快速腳本

for i in dir():
    print (i, sys.getsizeof(eval(i)) )

我如何確定Python中對象的大小?

答案是“只使用sys.getsizeof”並不是一個完整的答案。

這個答案直接適用於內建對象,但它沒有考慮這些對象可能包含的內容,特別是包含元組,列表,字典和集合等類型。 它們可以包含實例,以及數字,字符串和其他對象。

更完整的答案

使用來自Anaconda發行版的64位Python 2.7以及與guppy.hpy一起的sys.getsizeof ,我確定了以下對象的最小大小,並且請注意,sets和dicts預先分配了空間,所以空的不會再增長,直到一組金額(可能因語言的實施而有所不同):

Bytes  type        empty + scaling notes
24     int         NA
28     long        NA
37     str         + 1 byte per additional character
52     unicode     + 4 bytes per additional character
56     tuple       + 8 bytes per additional item
72     list        + 32 for first, 8 for each additional
232    set         sixth item increases to 744; 22nd, 2280; 86th, 8424
280    dict        sixth item increases to 1048; 22nd, 3352; 86th, 12568 *
64     class inst  has a __dict__ attr, same scaling as dict above
16     __slots__   class with slots has no dict, seems to store in 
                   mutable tuple-like structure.
120    func def    doesn't include default args and other attrs
904    class def   has a proxy __dict__ structure for class attrs
104    old class   makes sense, less stuff, has real dict though.

*請注意,字典( 但不是集合 )在Python 3.6中獲得更緊湊的表示

我認為每引用一個附加項目8個字節在64位機器上有很大的意義。 這8個字節指向包含的項目所在的內存中的位置。 如果我記得正確,4個字節是Python 2中unicode的固定寬度,但在Python 3中,str變為寬度等於字符最大寬度的unicode。

(有關插槽的更多信息, 請參閱此答案 )

遞歸訪問者獲得更完整的功能

為了覆蓋大部分這些類型,我編寫了這個遞歸函數來嘗試估計大多數Python對象的大小,包括大部分內建函數,collections模塊中的類型以及自定義類型(slotted和other):

import sys
from numbers import Number
from collections import Set, Mapping, deque

try: # Python 2
    zero_depth_bases = (basestring, Number, xrange, bytearray)
    iteritems = 'iteritems'
except NameError: # Python 3
    zero_depth_bases = (str, bytes, Number, range, bytearray)
    iteritems = 'items'

def getsize(obj_0):
    """Recursively iterate to sum size of object & members."""
    def inner(obj, _seen_ids = set()):
        obj_id = id(obj)
        if obj_id in _seen_ids:
            return 0
        _seen_ids.add(obj_id)
        size = sys.getsizeof(obj)
        if isinstance(obj, zero_depth_bases):
            pass # bypass remaining control flow and return
        elif isinstance(obj, (tuple, list, Set, deque)):
            size += sum(inner(i) for i in obj)
        elif isinstance(obj, Mapping) or hasattr(obj, iteritems):
            size += sum(inner(k) + inner(v) for k, v in getattr(obj, iteritems)())
        # Check for custom object instances - may subclass above too
        if hasattr(obj, '__dict__'):
            size += inner(vars(obj))
        if hasattr(obj, '__slots__'): # can have __slots__ with __dict__
            size += sum(inner(getattr(obj, s)) for s in obj.__slots__ if hasattr(obj, s))
        return size
    return inner(obj_0)

我測試它很隨便(我應該單元測試):

>>> getsize(['a', tuple('bcd'), Foo()])
344
>>> getsize(Foo())
16
>>> getsize(tuple('bcd'))
194
>>> getsize(['a', tuple('bcd'), Foo(), {'foo': 'bar', 'baz': 'bar'}])
752
>>> getsize({'foo': 'bar', 'baz': 'bar'})
400
>>> getsize({})
280
>>> getsize({'foo':'bar'})
360
>>> getsize('foo')
40
>>> class Bar():
...     def baz():
...         pass
>>> getsize(Bar())
352
>>> getsize(Bar().__dict__)
280
>>> sys.getsizeof(Bar())
72
>>> getsize(Bar.__dict__)
872
>>> sys.getsizeof(Bar.__dict__)
280

它在類定義和函數定義上有所分解,因為我沒有去追踪它們的所有屬性,但是因為它們只應該在內存中存在一次,所以它們的大小實際上並不重要。


只需使用sys模塊中定義的sys.getsizeof函數即可。

sys.getsizeof(object[, default])

以字節為單位返回對象的大小。 該對象可以是任何類型的對象。 所有內置對像都會返回正確的結果,但這不一定適用於第三方擴展,因為它是特定於實現的。

default參數允許定義一個值,如果對像類型沒有提供檢索大小的方法並且會導致TypeError ,則返回該值。

getsizeof調用對象的__sizeof__方法,並在垃圾收集器管理對象時添加額外的垃圾回收器開銷。

用法示例,在python 3.0中:

>>> import sys
>>> x = 2
>>> sys.getsizeof(x)
24
>>> sys.getsizeof(sys.getsizeof)
32
>>> sys.getsizeof('this')
38
>>> sys.getsizeof('this also')
48

如果你使用python <2.6並且沒有sys.getsizeof你可以使用這個擴展模塊 。 從來沒有使用它。


對於numpy數組, getsizeof不起作用 - 對我來說它總是返回40,原因是:

from pylab import *
from sys import getsizeof
A = rand(10)
B = rand(10000)

然後(在ipython中):

In [64]: getsizeof(A)
Out[64]: 40

In [65]: getsizeof(B)
Out[65]: 40

令人高興的是,雖然:

In [66]: A.nbytes
Out[66]: 80

In [67]: B.nbytes
Out[67]: 80000

你可以這樣做 :-

[condition] and [expression_1] or [expression_2] ;

例:-

print(number%2 and "odd" or "even")

如果數字是奇數,則打印“奇數”或如果數字是偶數則打印“偶數”。

結果: -如果condition為true,則執行exp_1,否則執行exp_2。

注意: - 0,None,False,emptylist,emptyString的計算結果為False。 並且除0之外的任何數據都評估為True。

以下是它的工作原理:

如果條件[條件]變為“真”,那麼將評估expression_1但不評估表達式_2。 如果我們“和”有0(零)的東西,結果總是很明顯。所以在下面的陳述中,

0 and exp

表達式exp將不會被評估,因為“和”0將始終求值為零,並且不需要計算表達式。 這就是編譯器本身在所有語言中的工作方式。

1 or exp

表達式exp根本不會被評估,因為“或”1總是為1.所以它不會費心去評估表達式exp,因為無論如何結果都是1。 (編譯器優化方法)。

但是如果是的話

True and exp1 or exp2

第二個表達式exp2將不會被評估為True,而當exp1不為false時True and exp1將為True。

同樣在

False and exp1 or exp2

表達式exp1將不會被計算,因為False等於寫0並且0表示“和”本身為0但是在exp1之後使用“或”,它將在“或”之後計算表達式exp2。

注意: -這種使用“或”和“和”的分支只能在expression_1的Truth值不為False(或0或None或emptylist []或emptystring''時使用。)因為expression_1變為如果為false,則將評估expression_2,因為exp_1和exp_2之間存在“或”。

如果您仍然想讓它適用於所有情況,無論exp_1和exp_2的真值是什麼,請執行以下操作: -

[condition] and ([expression_1] or 1) or [expression_2] ;







python object memory memory-management sizeof