You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

继承自ndarray派生类Points的Rectangle子类非超类数据初始化问题

问题根因

Python实例化类的执行顺序是先调用__new__构造类实例,只有__new__返回当前类的实例时,才会继续执行__init__做初始化。你当前的实现有两个核心问题:

  1. Rectangle没有重写__new__方法,实例化时会直接调用父类Points的__new__,而你传入的RectAttributes对象完全不符合Points.__new__要求的list_of_points入参逻辑,要么直接报错,要么构造出的实例不属于Rectangle类,导致__init__永远不会触发。
  2. 原有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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 21:18:03