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

Python子类J_Eig调用父类方法后变为Single_Ket实例,如何避免重写代码?

问题根源

报错的核心原因是父类Single_Ket的算术运算方法硬编码返回了Single_Ket类实例,子类J_Eig的实例经过乘法运算后类型会被向上转为父类,丢失子类的__rmatmul__方法,导致第二次调用@运算符时报错。


解决方案

不需要重写子类的所有算术方法,只要调整父类的实现逻辑即可实现零代码重复:

最优方案:父类增加实例创建辅助方法(解耦性最好)

给父类新增通用的同类型实例创建方法,子类只需重写该方法适配自己的初始化参数即可,不需要修改任何算术运算逻辑:

from sympy import Rational, sqrt, I
import sympy as sp

class Single_Ket:
    def __init__(self, label: tuple, ket_coefficient = 1):
        self.label = label
        self.coeff = ket_coefficient
    
    # 新增辅助方法:用于生成同类型的新实例,子类可重写
    def _new_instance(self, new_coeff):
        return Single_Ket(self.label, new_coeff)

    # 所有算术方法统一调用_new_instance,不再硬写返回类名
    def __mul__(self, Scalar_Const):
        return self._new_instance(self.coeff * Scalar_Const)
    
    def __rmul__(self, Scalar_Const):
        return self._new_instance(self.coeff * Scalar_Const)
    
    def __truediv__(self, Scalar_Const):
        if type(Scalar_Const) == int:
            new_coeff = Rational(self.coeff, Scalar_Const)
        else:
            new_coeff = self.coeff/Scalar_Const
        return self._new_instance(new_coeff)
    
    def __neg__(self):
        return self._new_instance(-self.coeff)

class J_Eig(Single_Ket):
    def __init__(self, j, m, Coeff = 1):
        super().__init__((j, m), Coeff)
        self.j = j
        self.m = m
        self.State_Coeff = Coeff
    
    # 重写父类辅助方法,返回J_Eig类型实例
    def _new_instance(self, new_coeff):
        return J_Eig(self.j, self.m, new_coeff)
    
    def __rmatmul__(self, X):
        # 优化判断逻辑:避免依赖dir返回值的顺序,稳定性更高
        if str(X) in {'J_Plus', 'J_Minus', 'J_Z'}:
            return eval(f'J_Op.{X}(self)')

class J_Op:
    @staticmethod
    def J_Plus(J_State):
        return sqrt(J_State.j*(J_State.j + 1) - J_State.m*(J_State.m + 1)) * J_Eig(J_State.j, J_State.m + 1, J_State.State_Coeff)

# 测试代码
psi = J_Eig(1, 0, 1)
psi_2 = 'J_Plus' @ psi
print('J_Plus' @ psi)
print('J_Plus' @ psi_2)

修改完成后,所有算术运算返回的实例类型和调用者完全一致,J_Eig实例乘完还是J_Eig类型,第二次调用@运算符不会再报错。


内容的提问来源于stack exchange,提问作者QF2QP

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 23:45:02