ctypes.c_int 与 ctypes.py_object 有何不同?

How does ctypes.c_int differs from ctypes.py_object?

我知道 multiplying 一个 ctype 和一个 integerdeclaring an array.

例如,ctypes.c_int * 4array of 4 integers.

py_object是什么?

请帮助我了解 ctypes.c_intctypes.py_object?

有何不同
from ctypes import c_int, py_object

# Array of (three) integers initialized such that
# a[0] = 1, a[1] = 2, a[2] = 3. 
a = (c_int * 3)(1, 2, 3) 

# Array of (three) arbitrary Python objects initialized
# such that a[0] = "Pizza", a[1] = 5, a[2] = 5.813.
b = (py_object * 3)("Pizza", 5, 5.813)

print(a[:]) # -> [1, 2, 3]
print(b[:]) # -> ['Pizza', 5, 5.813] 

正在尝试执行

a = (c_int * 3)("Pizza", 5, 5.813)

会生成一个TypeError: an integer is required (got type str).

这是因为我们已经指定我们想要一个包含三个元素的数组,所有元素都是整数,但我们也试图在数组中包含一个字符串。

与列表不同,数组要求所有元素 a[0], a[1], ... , a[n] 属于同一类型。

通过指定 py_object 而不是 c_int,您基本上可以拥有一个任意 Python 对象的数组,而不是只有整数。

严格来说(在 CPython 中),在内部,py_object 方式为您提供指向 PyObject 数据类型的指针数组。在内部,所有对象类型都是 PyObject.

的扩展

所以b数组的所有元素的类型都是指向PyObject的指针。指针只不过是一个内存地址。所以 b 数组的每个元素只是一个内存地址,指向 Python 中的某个任意对象。在内部,整数、浮点数、列表、字典等都是 PyObject,因此具有类型 py_object 元素的数组允许其元素是内存地址,这些内存地址实质上是指任何类型的对象Python(列表、元组、整数、浮点数等)。

当我们打印 b[0] 时,例如,Python 给我们 'Pizza' 作为输出。在内部,Python 为我们使用字符串对象的内存地址和 returns 字符串。

C 和 CPython 源代码中经常使用指针/内存地址。 Python 本质上对我们隐藏了内存地址,因为它是一种 high-level 语言,从 low-level 指针等概念中抽象出来。

希望对您有所帮助!