我想要改组ctype数组。当我尝试random.shuffle(myArray)
时出现错误(builtins.ValueError: PyObject is NULL
)
import ctypes
import random
def shuffleArray():
size = 10
myArray = (size*ctypes.py_object)()
random.shuffle(myArray)
for i in range(0,size):
myArray[i] = i
print(myArray[i])
答案 0 :(得分:2)
random.shuffle
只需交换随机索引值项即可。如果您首先初始化数组没有问题,以便不取消引用空指针:
>>> import ctypes, random
>>> my_array = (10 * ctypes.py_object)(*range(10))
>>> random.shuffle(my_array)
>>> my_array[:]
[5, 0, 4, 8, 6, 3, 7, 1, 2, 9]
我不知道为什么你需要py_object
而不是普通的C类型。这很不寻常。除非您确实需要将Python对象数组传递给库,否则应该使用常规C类型,例如c_long
,c_double
等。这些类型将Python对象的值转换为C数据类型。
这里有更多关于py_object
(类型'O')的内容。它是一个简单的指针类型,如c_void_p
(类型'P')。通过简单类型,我的意思是它是_ctypes._SimpleCData
的子类而不是_ctypes._Pointer
,因此它具有value
属性而不是contents
。 py_object
专门指向Python对象,在CPython中是对象的id
。构造函数保留对_objects
属性中对象的引用。这可以防止引用的对象被垃圾回收。
>>> obj = 'abc'
>>> pyobj = ctypes.py_object(obj)
>>> pyobj._objects is obj
True
>>> addr = ctypes.c_size_t.from_buffer(pyobj).value
>>> addr == id(obj)
True
type 'O' GETFUNC
(用于获取数组项,结构字段或函数调用结果)返回对Python对象的新引用。但它首先检查NULL
。这是你得到的ValueError
的来源。相比之下,在这种情况下,c_void_p
的{{3}}只返回None
:
>>> arr = (ctypes.c_void_p * 5)()
>>> random.shuffle(arr) # silly this is
>>> arr[:]
[None, None, None, None, None]
答案 1 :(得分:0)
import ctypes
import random
def shuffleArray():
size = 10
myArray = (size * ctypes.c_int)()
random.shuffle(myArray)
for i in range(0, size):
myArray[i] = i
print(myArray[i])
shuffleArray()
我认为您应该使用ctypes.c_int
代替ctypes.py_object
。
ctypes定义了许多原始的C兼容数据类型。 http://docs.python.org/2/library/ctypes.html