继承自ndarray派生类Points的Rectangle子类非超类数据初始化问题
问题根因
Python实例化类的执行顺序是先调用__new__构造类实例,只有__new__返回当前类的实例时,才会继续执行__init__做初始化。你当前的实现有两个核心问题:
Rectangle没有重写__new__方法,实例化时会直接调用父类Points的__new__,而你传入的RectAttributes对象完全不符合Points.__new__要求的list_of_points入参逻辑,要么直接报错,要么构造出的实例不属于Rectangle类,导致__init__永远不会触发。- 原有
Points.__new__里存在类型判断错误:type(list_of_points) == 'numpy.ndarray'是和字符串比较,永远返回False。
解决方案
你需要在Rectangle中重写__new__方法,先根据传入的RectAttributes生成点坐标,再调用父类的构造逻辑,额外的属性可以在__init__中赋值:
import numpy as np class Points(np.ndarray): def __new__(cls, list_of_points): # 修正类型判断错误 if isinstance(list_of_points, np.ndarray): obj = list_of_points.view(cls) else: obj = np.vstack(list_of_points).view(cls) return obj class Rectangle(Points): def __new__(cls, rect_attributes: RectAttributes): # 先根据属性生成矩形4个点的坐标 points = np.zeros((4, 2)) # 这里替换为你自己的construct_rect_from_attributes坐标计算逻辑 # 示例:读取RectAttributes的中心点、宽高、旋转角度计算四个顶点坐标 # ... 省略坐标计算实现 ... # 把生成的点传给父类的__new__构造实例 return super().__new__(cls, points) @init_args def __init__(self, rect_attributes: RectAttributes): print('in rect constructor') self.attributes = rect_attributes # 无需调用super().__init__,numpy ndarray的构造逻辑全部在__new__中完成
补充说明
- numpy ndarray子类的核心构造逻辑全部在
__new__中完成,__init__仅用来给实例追加自定义属性。 - 你原有逻辑中的坐标计算可以拆分:核心点坐标生成放到
__new__中执行,和属性相关的额外处理放到__init__中即可。
内容的提问来源于stack exchange,提问作者Jordan Larson
相关产品推荐
相关产品推荐

