确定对象是否是ctypes数组

时间:2014-01-13 20:55:48

标签: python ctypes

我想编写一个可以将本机Python列表或ctypes数组作为参数的函数。我可以使用

检测前者
isinstance(the_parameter, list)

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

编辑:如果将ctypes数组传递给我的函数,我只想把它变成一个列表。我意识到我可以做到

python_list = list(python_list_or_ctypes_array)

无论the_parameter是Python列表还是ctypes数组,都会给出一个列表。我会在这里留下这个问题,因为我仍然对答案感兴趣。

2 个答案:

答案 0 :(得分:8)

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[:]

答案 1 :(得分:2)

最简单(也可能是大多数Pythonic)的方法是将参数作为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