为子类化NumPy数组添加私有属性遇问题求助
问题原因
你犯了两个关键错误:
- 在
__new__方法里仍然给实例设置的是info属性,而非目标私有属性_info; - 在
__array_finalize__中尝试从原始普通ndarray对象(即np.asarray(arr)生成的实例)获取info属性——这个原始数组根本没有info属性,所以getattr返回默认值None,最终导致self._info被设为None。
具体执行顺序拆解:
- 调用
RealisticInfoArray(arr, info='information')时,先执行__new__里的np.asarray(input_array).view(cls),这一步会创建子类实例并触发__array_finalize__; - 此时
__array_finalize__的参数obj是原始普通ndarray(无info属性),所以self._info被赋值为None; - 之后
__new__里给实例设置了obj.info = info,但这和_info属性无关,最终obj._info仍为None。
修复方法
调整__new__和__array_finalize__,统一使用私有属性_info即可:
import numpy as np class RealisticInfoArray(np.ndarray): def __new__(cls, input_array, info=None): obj = np.asarray(input_array).view(cls) # 直接设置私有属性 _info obj._info = info return obj def __array_finalize__(self, obj): if obj is None: return # 从父对象获取私有属性 _info self._info = getattr(obj, '_info', None) arr = np.arange(5) obj = RealisticInfoArray(arr, info='information') print(obj._info) # 输出: information
如果你想保留info作为公共属性接口,同时用_info存储私有数据,可以添加属性装饰器:
import numpy as np class RealisticInfoArray(np.ndarray): def __new__(cls, input_array, info=None): obj = np.asarray(input_array).view(cls) obj._info = info return obj def __array_finalize__(self, obj): if obj is None: return self._info = getattr(obj, '_info', None) # 公共属性接口,内部映射到私有存储 @property def info(self): return self._info @info.setter def info(self, value): self._info = value arr = np.arange(5) obj = RealisticInfoArray(arr, info='information') print(obj._info) # 输出: information print(obj.info) # 输出: information obj.info = "new info" print(obj._info) # 输出: new info
内容的提问来源于stack exchange,提问作者slaw
相关产品推荐
相关产品推荐

