如何实现Gaussian类与未在类中定义的数字相乘?
修复Gaussian类与数字的乘法问题
问题描述
使用Gaussian类表示高斯函数时,已实现两个类实例间的乘法,但无法实现实例与整数、浮点数这类普通数字的乘法。测试代码如下:
g1=Gaussian(3,-1) g2=g1*3 print(g2) g3=g2*2.5 print(g3)
预期效果是将Gaussian实例的self.a属性与数字相乘,但运行时始终报错:'int' object has no attribute a。
当前Gaussian类代码:
import math class Gaussian: def __init__(self, a=1, b=2): self.a = a self.b = b def __str__(self): return("%s*exp(-(x**2/%s))"%(self.a,self.b**2)) def derive(self): a = (self.a*-2)/(self.b**2) b = self.b return(str(Gaussian(a,b)) + "*x") def __mul__(self,multi): a = self.a*multi.a b = self.b**2 b = math.sqrt((1/((multi.b**2)/(b*multi.b**2)+(b)/((multi.b**2)*b)))) return(str(Gaussian(a,b))) def __truediv__(self,divide): if self.a == divide.a*-1: return(-1.0) else: diva = self.a/divide.a divb = self.b**2 divb2 = divide.b**2 divb += math.sqrt(1/((divb2)/(divb*divb2)-(divb/(divb2*divb)))) return(str(Gaussian(diva,divb)))
错误原因
当前__mul__方法默认认为传入的multi参数是Gaussian实例,直接访问其a属性。但当传入整数或浮点数时,这些基础类型没有a属性,因此触发报错。
解决方案
修改__mul__方法,先判断参数类型:如果是数字(int/float),仅将实例的self.a与数字相乘,保持self.b不变;如果是Gaussian实例,执行原有的实例间相乘逻辑。同时实现__rmul__方法,支持数字*实例的反向乘法操作。
修改后的完整代码:
import math class Gaussian: def __init__(self, a=1, b=2): self.a = a self.b = b def __str__(self): return("%s*exp(-(x**2/%s))"%(self.a,self.b**2)) def derive(self): a = (self.a*-2)/(self.b**2) b = self.b return(str(Gaussian(a,b)) + "*x") def __mul__(self, multi): # 处理与数字的乘法 if isinstance(multi, (int, float)): new_a = self.a * multi return Gaussian(new_a, self.b) # 处理与Gaussian实例的乘法 elif isinstance(multi, Gaussian): a = self.a * multi.a # 简化原有的b值计算逻辑 b_sq_self = self.b ** 2 b_sq_multi = multi.b ** 2 combined_b_sq = (b_sq_self * b_sq_multi) / (b_sq_self + b_sq_multi) new_b = math.sqrt(combined_b_sq) return Gaussian(a, new_b) else: raise TypeError("不支持与该类型相乘") def __rmul__(self, multi): # 支持数字在前的乘法,复用__mul__逻辑 return self.__mul__(multi) def __truediv__(self, divide): # 新增数字除法支持 if isinstance(divide, (int, float)): new_a = self.a / divide return Gaussian(new_a, self.b) elif isinstance(divide, Gaussian): if self.a == divide.a * -1: return -1.0 else: diva = self.a / divide.a divb_sq_self = self.b ** 2 divb_sq_divide = divide.b ** 2 # 简化b值计算逻辑 combined_b_sq = (divb_sq_self * divb_sq_divide) / (divb_sq_divide - divb_sq_self) new_b = math.sqrt(combined_b_sq) return Gaussian(diva, new_b) else: raise TypeError("不支持与该类型相除")
关键说明
- 通过
isinstance(multi, (int, float))判断参数类型,区分数字与Gaussian实例,分别执行对应逻辑 __rmul__方法用于支持3*g1这类数字在前的乘法操作,Python会在实例的__mul__无法处理时自动调用该方法- 优化了原有的实例间相乘/相除的b值计算逻辑,简化公式,提升可读性
- 同时给
__truediv__方法也添加了数字处理逻辑,让除法也支持与普通数字运算
内容的提问来源于stack exchange,提问作者Collin Hensel
相关产品推荐
相关产品推荐

