确定一个对象是否为ctypes数组

4

我希望编写一个函数,可以接受原生的Python列表或ctypes数组作为参数。通过以下方法可以检测到前者:

isinstance(the_parameter, list)

如何确定给定的变量是否引用了ctypes数组?

编辑:如果一个ctypes数组被传递到我的函数中,我只想将其转换为列表。我意识到可以这样做:

python_list = list(python_list_or_ctypes_array)

无论 the_parameter 是 Python 列表还是 ctypes 数组,都将提供一个列表。我会留下这个问题,因为我仍然对答案感兴趣。
2个回答

12

isinstance(the_parameter, ctypes.Array)会检查一个ctypes数组。

ctypes定义了以下简单标量类型(注意,它们是私有的):

_SimpleCData # _type_: 'P' for void *
_Pointer     # _type_: ctypes.c_int
_CFuncPtr    # _flags_, _restype_, _argtypes_, _check_retval_

虽然您可以直接子类化这些类型,但大多数情况下应使用现有的子类和工厂函数,例如c_void_pPOINTERCFUNCTYPE

ctypes定义了以下聚合类型:

Array        # _type_, _length_
Structure    # _fields_, _anonymous_, _pack_, _swappedbytes_
Union        # _fields_, _anonymous_, _pack_, _swappedbytes_

Array子类通常是使用*运算符进行序列重复创建的,例如:IntArray = c_int * 10。你也可以使用以下方法:

class IntArray(ctypes.Array):
    _type_ = ctypes.c_int
    _length_ = 10

a = IntArray(*range(10))
a_list = a[:]

2
最简单(可能也是最符合Python风格的)方法是一开始将参数视为ctypes数组,然后在参数因行为不同而不是ctypes数组时捕获引发的任何异常。由于ctypes数组实现了迭代,只要你在Python端正确定义了结构体和ctypes数组,你就可以在大多数情况下交替使用Python列表和ctypes数组。这是假设你有一个实际的ctypes数组而不仅仅是一个指向C端数组的指针,但在那种情况下,你无论如何都必须以某种方式跟踪数组长度,而且ctypes指针可以像数组一样进行索引,因此如果你必须为它们提供长度,则可以在函数中将 `size` 作为默认值为 `None` 的参数,并使用 `for i in range(size or len(the_parameter)): the_parameter[i] # do stuff` 进行遍历。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接