gpt4 book ai didi

python - __sizeof__ 没有被 sys.getsizeof 调用

转载 作者:太空宇宙 更新时间:2023-11-03 14:07:38 24 4
gpt4 key购买 nike

我正在用 Python 编写一个动态数组实现(类似于内置的列表类),为此我需要观察容量的增长(每次达到限制时都会翻倍)。为此,我有以下代码,但输出很奇怪。看起来 sys.getsizeof() 从未调用我类(class)的 __sizeof__()。出于测试目的,我正在使 __sizeof__() 返回 0,但根据 sys.getsizeof(),它是非零。

有什么收获?

import ctypes

class DynamicArray(object):
'''
DYNAMIC ARRAY CLASS (Similar to Python List)
'''

def __init__(self):
self.n = 0 # Count actual elements (Default is 0)
self.capacity = 1 # Default Capacity
self.A = self.make_array(self.capacity)

def __len__(self):
"""
Return number of elements sorted in array
"""
return self.n

def __getitem__(self,k):
"""
Return element at index k
"""
if not 0 <= k <self.n:
return IndexError('K is out of bounds!') # Check it k index is in bounds of array

return self.A[k] #Retrieve from array at index k

def append(self, ele):
"""
Add element to end of the array
"""
if self.n == self.capacity:
self._resize(2*self.capacity) #Double capacity if not enough room

self.A[self.n] = ele #Set self.n index to element
self.n += 1

def _resize(self,new_cap):
"""
Resize internal array to capacity new_cap
"""
print("resize called!")

B = self.make_array(new_cap) # New bigger array

for k in range(self.n): # Reference all existing values
B[k] = self.A[k]

self.A = B # Call A the new bigger array
self.capacity = new_cap # Reset the capacity

def make_array(self,new_cap):
"""
Returns a new array with new_cap capacity
"""
return (new_cap * ctypes.py_object)()

def __sizeof__(self):
return 0

用于测试调整大小的代码:

arr2 = DynamicArray()

import sys

for i in range(100):
print(len(arr2), " ", sys.getsizeof(arr2))
arr2.append(i)

输出:

0   24
1 24
resize called!
2 24
resize called!
3 24
4 24
resize called!
5 24
6 24
7 24
8 24
resize called!
9 24
10 24
11 24
12 24
13 24
14 24
15 24
16 24
resize called!
17 24
18 24
19 24
20 24
21 24
22 24
23 24
24 24
25 24
26 24
27 24
28 24
29 24
30 24
31 24
32 24
resize called!
33 24
34 24
35 24
36 24
37 24
38 24
39 24
40 24
41 24
42 24
43 24
44 24
45 24
46 24
47 24
48 24
49 24
50 24
51 24
52 24
53 24
54 24
55 24
56 24
57 24
58 24
59 24
60 24
61 24
62 24
63 24
64 24
resize called!
65 24
66 24
67 24
68 24
69 24
70 24
71 24
72 24
73 24
74 24
75 24
76 24
77 24
78 24
79 24
80 24
81 24
82 24
83 24
84 24
85 24
86 24
87 24
88 24
89 24
90 24
91 24
92 24
93 24
94 24
95 24
96 24
97 24
98 24
99 24

最佳答案

您的 __sizeof__ 正在 被调用,它只是将垃圾收集器开销添加到它,这就是结果不为零的原因。

From the docs on sys.getsizeof :

getsizeof() calls the object’s __sizeof__ method and adds an additional garbage collector overhead if the object is managed by the garbage collector.

返回 0 是一种让您自己难以理解它被调用的方式,因为您总是会得到相同的结果(0 + 开销).

根据动态数组的内容返回一个大小以查看它的变化。


进一步阐述:

CPython 中的每个对象都在 PyGC_head 结构中附加了一些管理信息 that gets added :

/* add gc_head size */
if (PyObject_IS_GC(o))
return ((size_t)size) + sizeof(PyGC_Head);
return (size_t)size;

由垃圾收集器使用。

为什么将其添加到总体大小可能是因为它确实代表了对象所需的额外内存。在 Python 级别,您无需担心垃圾收集并将其视为魔术,但是,在询问有关对象大小的信息时,您不应该为了保持幻觉而牺牲正确的结果。

关于python - __sizeof__ 没有被 sys.getsizeof 调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42051378/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com