Python跨类调用实例方法报位置参数错误该如何解决
报错原因
Python类的实例方法在调用时,实例本身会被自动作为第一个参数传入方法的self形参,无需手动传递。
你在调用self._ball.time_to_collision(self._ball, self._container)时:
self._ball自动传入作为time_to_collision的第一个参数self- 你手动传入的
self._ball、self._container成为了第二、第三个参数
而time_to_collision仅定义了self和other两个形参,因此触发参数数量不匹配的类型错误。
修复方案
1. 修正碰撞时间方法的调用逻辑
仅需将容器实例作为唯一的显式参数传入即可:
# 错误写法 self._ball.time_to_collision(self._ball, self._container) # 正确写法 self._ball.time_to_collision(self._container)
2. 修复其他潜在问题
你当前的代码还有多个隐含错误,会在修复参数问题后继续触发报错,需同步修改:
- 修复Container类初始化逻辑:Container继承Ball但未调用父类构造方法,实例会缺少
pos、vel等必要属性:
class Container(Ball): def __init__(self, radius = 10): # 容器固定在原点,速度为0,质量设为无穷大避免碰撞后位移 super().__init__(pos=np.array([0,0]), vel=np.array([0,0]), mass=float('inf'), radius=radius)
- 修正time_to_collision计算错误:半径差是标量,无需用
np.dot计算平方:
def time_to_collision(self, other): posdif = np.subtract(self.pos, other.pos) veldif = np.subtract(self.vel, other.vel) raddif = self.radius - other.radius return (-2*np.dot(posdif, veldif) + np.sqrt(4*(np.dot(posdif, veldif)**2)-4*np.dot(veldif, veldif)*(np.dot(posdif, posdif)- raddif**2)))/(2*np.dot(veldif, veldif))
- 修正move方法逻辑:原方法仅返回新位置,没有更新实例自身的pos属性,无法真正修改球的位置:
def move(self, dt): self.pos = np.add(self.pos, np.dot(self.vel, dt)) return self.pos
- 修正collide方法逻辑:不要依赖其他方法设置的实例属性,避免未先计算碰撞时间就调用碰撞处理时报错,同时更新实例自身的速度:
def collide(self, other): posdif = np.subtract(self.pos, other.pos) veldif = np.subtract(self.vel, other.vel) self.vel = self.vel - (np.dot(veldif, posdif)*posdif)/(np.dot(posdif,posdif)) return self.vel
- 完善next_collision完整逻辑:
def next_collision(self): # 计算球和容器的碰撞时间 collide_time = self._ball.time_to_collision(self._container) # 将球移动到碰撞时刻的位置 self._ball.move(collide_time) # 处理碰撞更新球的速度 self._ball.collide(self._container) # 可按需返回碰撞时间等信息 return collide_time
内容的提问来源于stack exchange,提问作者sid2001
相关产品推荐
相关产品推荐

