使用ctypes.py_object在python中实现数组类



这是代码的第一部分

from ctypes import py_object
from typing import TypeVar, Generic
T = TypeVar('T')

class ArrayR(Generic[T]):
def __init__(self, length: int) -> None:
""" Creates an array of references to objects of the given length
:complexity: O(length) for best/worst case to initialise to None
:pre: length > 0
"""
if length <= 0:
raise ValueError("Array length should be larger than 0.")
self.array = (length * py_object)() # initialises the space
self.array[:] =  [None for _ in range(length)]
def __setitem__(self, index: int, value: T) -> None:
""" Sets the object in position index to value
:complexity: O(1)
:pre: index in between 0 and length - self.array[] checks it
"""
self.array[index] = value

我知道self.array = (length * py_object)()正在实例化ctypes.py_object * size类型。但是self.array[:] = [None for _ in range(length)]是如何工作的呢?

如果你不介意的话,你能解释一下是什么吗

实例化类型

做进一步的细节?

谢谢。

int为类型。int()创建该类型的实例:

>>> int
<class 'int'>
>>> int()
0

pyobject * length也是一个类型,(pyobject * length)()创建一个该类型的实例:

>>> from ctypes import *
>>> py_object * 5
<class '__main__.py_object_Array_5'>
>>> (py_object * 5)()
<__main__.py_object_Array_5 object at 0x000002306F5C59C0>

但是py_object封装了cPyObject*并且初始化为cNULL:

>>> a = (py_object * 5)()
>>> a
<__main__.py_object_Array_5 object at 0x000002306FADACC0>
>>> a[0]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: PyObject is NULL

[None for _ in range(5)]创建一个PythonNone对象列表。使用切片表示法,py_object数组元素被赋值来包装每个None对象:

>>> a[:] = [None for _ in range(5)]
>>> a
<__main__.py_object_Array_5 object at 0x000002306FADACC0>
>>> print(a[0])
None
>>> print(a[4])
None

注意,如果没有切片符号来替换现有列表中的所有元素,a = [None for _ in range(5)]将只创建一个新的Python Nones列表,它将不是py_object数组:

>>> a = [None for _ in range(5)]
>>> a
[None, None, None, None, None]

最新更新