__未被呼叫系统获取大小

2024-03-28 09:11:20 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在用Python编写一个动态数组实现(类似于内置的list类),对于这个实现,我需要观察容量的增长(每次达到限制时,它都会翻倍)。为此,我有以下代码,但输出很奇怪。看起来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

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

^{pr2}$

以及输出:

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

Tags: oftoselfnewindexmakereturnis
1条回答
网友
1楼 · 发布于 2024-03-28 09:11:20

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

From the docs on ^{}

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级别上,您不需要担心垃圾的收集,并将其视为魔法,但是,当您询问对象大小的信息时,您不应该仅仅为了保持幻觉而牺牲正确的结果。在

相关问题 更多 >