我想编写一个可以将本机Python列表或ctypes数组作为参数的函数。我可以使用
检测前者isinstance(the_parameter, list)
如何确定给定变量是否引用ctypes数组?
编辑:如果将ctypes数组传递给我的函数,我只想把它变成一个列表。我意识到我可以做到
python_list = list(python_list_or_ctypes_array)
无论the_parameter
是Python列表还是ctypes数组,都会给出一个列表。我会在这里留下这个问题,因为我仍然对答案感兴趣。
答案 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_p
,POINTER
和CFUNCTYPE
。
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
。