2014-01-13 8 views
1

Я хотел бы написать функцию, которая может принимать как собственный список Python, так и массив ctypes в качестве параметра. Я могу обнаружить первый, используяОпределение того, является ли объект массивом ctypes

isinstance(the_parameter, list) 

Как определить, относится ли данная переменная к массиву ctypes?

Редактировать: В случае, когда массив ctypes был передан моей функции, я просто хотел превратить его в список в любом случае. Я понял, что я могу сделать

the_list = list(the_parameter) 

который даст список независимо от того, был ли the_parameter список Python или массив ctypes. Я оставлю этот вопрос здесь, потому что меня все еще интересует ответ.

ответ

6

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

Простейший (и, возможно, самый Pythonic) способ заключается в том, чтобы рассматривать параметр как массив ctypes, чтобы начать с него, а затем поймать любое исключение, если параметр окажется не массив ctypes из-за различного поведения. Поскольку массивы ctypes реализуют итерацию, то до тех пор, пока вы правильно определили свои структуры и массивы ctypes на стороне Python, вы должны иметь возможность использовать как списки Python, так и массивы ctypes взаимозаменяемо в большинстве случаев. Предполагается, что у вас есть фактический массив ctypes, а не только указатель на массив на стороне C, но в тех случаях, когда вам нужно будет отслеживать длину массива как-то в любом случае, а указатели ctypes могут быть проиндексированы как массивы поэтому, если вам нужно указать длину для тех, у кого может быть size, в качестве аргумента для вашей функции по умолчанию None, а затем с помощью for i in range(size or len(the_parameter)): the_parameter[i] # do stuff.

Смежные вопросы