Вопрос

I’d like to write a function that can take either a native Python list or a ctypes array as a parameter. I can detect the former using

isinstance(the_parameter, list)

How can I determine whether a given variable refers to a ctypes array?

Edit: In the case that a ctypes array was passed to my function, I just wanted to turn it into a list anyway. I realized that I can do

python_list = list(python_list_or_ctypes_array)

which will give a list regardless of whether the_parameter was a Python list or a ctypes array. I’ll leave this question here because I’m still interested in an answer.

Это было полезно?

Решение

isinstance(the_parameter, ctypes.Array) will check for a ctypes array.

ctypes defines the following simple scalar types (note, they're private):

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

While you can subclass these types directly, for the most part you should use the existing subclasses and factory functions such as c_void_p, POINTER and CFUNCTYPE.

ctypes defines the following aggregate types:

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

Array subclasses are typically created by sequence repetition using the * operator, e.g. IntArray = c_int * 10. You could instead use the following:

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

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

Другие советы

The simplest (and possibly most Pythonic) way would be to treat the parameter as a ctypes array to begin with and then catching whatever exception would be raised when the parameter turns out to not be a ctypes array due to differing behavior. As ctypes arrays implement iteration, then as long as you've defined your structs and ctypes arrays correctly on the Python side you should be able to use both Python lists and ctypes arrays interchangeably in most circumstances. This is assuming you have an actual ctypes array and not just a pointer to an array on the C side, but in cases like those you'd have to be keeping track of the array length somehow anyway, and ctypes pointers can be indexed like arrays so if you have to possibly supply a length for those you could have size as an argument to your function defaulting to None and then using for i in range(size or len(the_parameter)): the_parameter[i] # do stuff.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top