在 Python 类方法中使用递归时遇到了问题,具体表现为:
- 试图在 Python 类方法中使用递归,但结果有限。
- 正在尝试构建一个车类,具有非常基本的属性:id、单车道位置(用整数表示)和速度。
- 其中一个函数用于返回该车紧跟在后面的车的 id -- 即如果我们有类:
class Car:
def __init__(self, position, id, velocity):
self.position = position
self.id = id
self.velocity = velocity
- 现在,想出了以下类方法(更多详细信息在代码下方):
def findSuccessorCar(self, cars):
successorCar = ""
smallestGapFound = 20000000
for car in cars:
if car.id == self.id: continue
currentGap = self.calculateGap(car)
if (currentGap > -1) and (currentGap < smallestGapFound):
smallestGapFound = currentGap
successorCar = car
if successorCar == "":
return 1 # calling code checks for 1 as an error code
else:
return successorCar
- 计划创建汽车对象,然后将它们存储在一个列表中。
- 每次调用 findSuccessorMethod 时,都会将这个汽车的全局列表传递给它,例如:
c1 = testCar.Car(4, 5, 1) # position, pos_y, Vel, ID
c2 = testCar.Car(7, 9, 2)
c3 = testCar.Car(9, 1, 2)
cars = [c1, c2, c3]
c1_succ = c1.findSuccessorCar(cars)
-
这工作得很好:
find successor car函数会说汽车 c2 位于汽车 c1 的前面(位置 7 位于位置 4 的前面)。 -
但是,希望汽车 c1 找出紧跟在它直接的后继的汽车 -- 也就是哪个汽车位于前面的汽车的前面,在这种情况下是汽车 c3。
-
我的想法是,如果我执行 c1_succ.findSuccessorCars(cars) 那么这应该可以正常工作:执行 type(c1_succ) 显示它是一个实例,而 hasattr 显示它具有预期的对象属性。
-
然而,当我确实尝试执行 c1_succ.findSuccessorCars(cars) 时,返回了一个整数。因此,我感到困惑 -- 为什么这不起作用?为什么不能以这种方式递归执行类方法?这个整数是从哪里来的?
-
直觉告诉我这与 self 声明有关,并且我需要修改代码,以便除汽车的全局列表外,还需要一个它们当前位置的全局列表,或另一个类方法,例如 findSuccessorsSuccessor(是的,我完全意识到命名不当!)然而,有兴趣了解为什么这种递归方法不起作用。
-
下面是计算两辆汽车之间间隙的请求代码 -- 我很感激它非常基本,所以请不要在后面大笑。
def calculateGap(self, car):
''' Calculate the gap between two cars
'''
thisCar = self
otherCar = car
gap = otherCar.position_x - thisCar.position_x
return gap
- 解决方案
- 正在尝试使用实例方法而不是类方法。类方法作用于类,实例方法作用于实例。
- 在这里,正在处理 Car 实例,而不是 Car 类本身。
- 正确的方法是使用实例方法,而不是类方法。
- 实例方法可以使用 self 作为第一个参数,self 是实例的引用。
- 类方法可以使用 cls 作为第一个参数,cls 是类的引用。
- 可以使用以下代码来实现:
class Car:
def __init__(self, position, id, velocity):
self.position = position
self.id = id
self.velocity = velocity
def findSuccessor(self, cars):
ret = smallestGap = None
for car in cars:
if car == self:
continue
gap = self.calculateGap(car)
if gap < 0:
continue
if smallestGap is None or gap < smallestGap:
ret, smallestGap = car, gap
return ret
def findNthSuccessor(self, n, cars):
cur = self
for x in xrange(n):
cur = cur.findSuccessor(cars)
if cur is None:
return None
return cur
c1 = Car(4, 5, 1)
c2 = Car(7, 9, 2)
c3 = Car(9, 1, 2)
cars = [c1, c2, c3]
print c1.findSuccessor(cars)
print c1.findSuccessor(cars).findSuccessor(cars)
print c1.findNthSuccessor(2, cars)
Output:
Car(7, 9, 2)
Car(9, 1, 2)
Car(9, 1, 2)