2014-01-13 150 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_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

最簡單的(也可能是大多數Pythonic)方法是將參數作爲一個ctypes數組來處理,然後捕獲由於不同行爲而導致參數不是ctypes數組時會引發的異常。由於ctypes數組實現了迭代,因此只要您在Python端正確定義了structs和ctypes數組,就可以在大多數情況下交替使用Python列表和ctypes數組。這是假設你有一個實際的ctypes數組,而不僅僅是一個指向C端數組的指針,但是在那些情況下,你必須以某種方式跟蹤數組的長度,並且ctypes指針可以像數組一樣索引所以如果你必須提供一個長度,你可以用size作爲你的函數的參數,默認爲None,然後使用for i in range(size or len(the_parameter)): the_parameter[i] # do stuff

相關問題