ank*_*981 3 python class python-3.x
我正在用Python写一个动态数组实现(类似于内置列表类),为此我需要观察容量的增长(每次达到限制时都会增加一倍).为此,我有以下代码,但输出很奇怪.看起来好像sys.getsizeof()永远不会叫我的班级__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
Run Code Online (Sandbox Code Playgroud)
用于测试调整大小的代码:
arr2 = DynamicArray()
import sys
for i in range(100):
print(len(arr2), " ", sys.getsizeof(arr2))
arr2.append(i)
Run Code Online (Sandbox Code Playgroud)
并输出:
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
Run Code Online (Sandbox Code Playgroud)
你__sizeof__ 是获取调用,它只是增加垃圾收集开销它这就是为什么结果不是零.
getsizeof()__sizeof__如果对象由垃圾收集器管理,则调用该对象的方法并添加额外的垃圾收集器开销.
返回0是一种让你自己很难理解它被调用的方法,因为你总会得到相同的结果(0+开销).
返回基于动态数组内容的大小以查看其更改.
进一步阐述:
CPython中的每个对象都在一个添加的PyGC_head结构中附加了一些管理信息:
/* add gc_head size */
if (PyObject_IS_GC(o))
return ((size_t)size) + sizeof(PyGC_Head);
return (size_t)size;
Run Code Online (Sandbox Code Playgroud)
垃圾收集器使用的.
为什么将它添加到整体大小可能是因为它确实代表了对象所需的额外内存.在Python级别,您不需要担心垃圾的收集并将其视为魔法,但是,当询问有关对象大小的信息时,您不应该牺牲正确的结果来保持幻觉生存.
| 归档时间: |
|
| 查看次数: |
308 次 |
| 最近记录: |