设置numpy.ndarray.data属性报错:Python3.8与3.9版本兼容问题
NumPy 3.9中
ndarray.data无法赋值问题解析 问题现象
以下代码在Python3.8环境中可正常执行:
import numpy as np import ctypes img = np.empty((10, 10), dtype=np.uint8) a=(ctypes.c_uint8 * 100)() img.data=a
但在Python3.9中运行时会抛出错误:
Traceback (most recent call last): File "", line 1, in AttributeError: attribute 'data' of 'numpy.ndarray' objects is not writable
查看该数组的flags属性,WRITEABLE标记明明为True:
img.flags C_CONTIGUOUS : True F_CONTIGUOUS : False OWNDATA : True WRITEABLE : True ALIGNED : True WRITEBACKIFCOPY : False
原因解析
ndarray.data属性的可写性和数组的WRITEABLE标记是完全独立的两个概念:
- 数组的
WRITEABLE标记控制的是数组元素是否允许被修改,比如img[0,0] = 255这类操作的合法性。 - 而
ndarray.data是指向数组底层缓冲区的指针属性,在NumPy 1.20及以后版本中,该属性被改为只读,目的是避免用户直接修改指针导致内存管理混乱、缓冲区失效等问题。Python3.9通常搭配的NumPy版本已更新到这一规范,因此会触发错误;而Python3.8对应的旧版NumPy中data属性仍为可写,所以能正常运行。
替代解决方案
如果需要将ctypes数组与NumPy数组关联,推荐使用np.frombuffer方法,这是NumPy官方认可的安全用法,在Python3.9及更高版本中均可正常工作:
import numpy as np import ctypes # 创建ctypes数组 a = (ctypes.c_uint8 * 100)() # 从ctypes数组的缓冲区创建NumPy数组并调整形状 img = np.frombuffer(a, dtype=np.uint8).reshape(10, 10)
内容的提问来源于stack exchange,提问作者gamesun
相关产品推荐
相关产品推荐

