This is first part of code.
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
I know self.array = (length * py_object)()
is instantiating ctypes.py_object * size
type. But how does self.array[:] = [None for _ in range(length)]
work?
If you don't mind, can you explain what does
instantiating type
do in further detail?
Thanks.
int
is a type.int()
creates an instance of that type:pyobject * length
is also a type,(pyobject * length)()
creates an instance of that type:But
py_object
wraps a CPyObject*
and is initialized to CNULL
:[None for _ in range(5)]
creates a list of PythonNone
objects. Using slice notation, the py_object array elements are assigned to wrap each None object:Note without slice notation used to replace all elements in the existing list,
a = [None for _ in range(5)]
would just create a new Python list of Nones and it would not be a py_object array: