使用Python Turtle绘制梯形内同心圆时遇RecursionError:如何修复?
递归深度超限错误的原因及修复方案
错误原因
- 无限递归触发深度限制:你的
nums()和a()都用递归实现循环尝试,但没有合理的终止条件:a()里用side_1 + side_2 == x3 - x2 + abs(x1)做判断,这是浮点数精确相等比较。由于浮点数计算存在精度误差,两个结果完全相等的概率极低,导致else分支被无限触发,递归调用次数超过Python默认的递归深度(约1000次),抛出RecursionError。nums()的条件判断逻辑有误:and优先级高于or,原条件实际逻辑并非“只要任意变量超出[-150,150]就保留”,可能导致循环递归生成新值,增加触发深度超限的风险。
- 参数合法性问题:
x3_solve()中randrange(x2 + 1, x2 + abs(x1) - 21)的区间可能无效(比如abs(x1) ≤22时,起始值大于等于结束值),会直接导致randrange报错,而递归会不断重复这个错误调用。
修复方案
1. 替换递归为循环
递归不适合这种需要多次尝试的场景,改用while循环可以彻底避免递归深度限制问题。
2. 修正浮点数比较逻辑
用近似相等替代精确相等,设置合理的误差阈值(如1e-6),判断计算值的差值是否在阈值内。
3. 修正参数生成逻辑
- 确保
x1的绝对值大于22,保证x3_solve()的区间有效; - 修正变量范围检查的条件逻辑,明确判断优先级。
修复后的代码
import turtle as t import random as r p1 = t.Pen() p1.speed(1) def x1_solve(): # 确保abs(x1) >22,保证x3_solve的区间有效 while True: x1 = r.randrange(-300, 300) if abs(x1) > 22: return x1 def x2_solve(): return r.randrange(-300, 300) def y2_solve(): return r.randrange(0, 250) def x3_solve(x2, x1): return r.randrange(x2 + 1, x2 + abs(x1) - 21) # 生成符合范围的参数,用循环替代递归 x1 = x1_solve() x2 = x2_solve() y2 = y2_solve() x3 = x3_solve(x2, x1) # 修正条件判断:只要任意变量超出[-150,150]就保留,否则重新生成 while not (x1 > 150 or x1 < -150 or x2 > 150 or x2 < -150 or x3 > 150 or x3 < -150): x1 = x1_solve() x2 = x2_solve() y2 = y2_solve() x3 = x3_solve(x2, x1) # 计算侧边长度 if x1 > 0: side_1 = ((x2 + x1/2)**2 + (y2)**2)**0.5 side_2 = ((x3 - x1/2)**2 + (y2)**2)**0.5 else: side_1 = ((x2 - x1/2)**2 + (y2)**2)**0.5 side_2 = ((x3 - abs(x1/2))**2 + (y2)**2)**0.5 # 用循环+近似相等替代递归判断 threshold = 1e-6 # 误差阈值 while abs(side_1 + side_2 - (x3 - x2 + abs(x1))) > threshold: x3 = x3_solve(x2, x1) # 重新计算侧边长度 if x1 > 0: side_1 = ((x2 + x1/2)**2 + (y2)**2)**0.5 side_2 = ((x3 - x1/2)**2 + (y2)**2)**0.5 else: side_1 = ((x2 - x1/2)**2 + (y2)**2)**0.5 side_2 = ((x3 - abs(x1/2))**2 + (y2)**2)**0.5 print(x3) # 绘制梯形 p1.goto(x=abs(x1/2), y=0) p1.pendown() p1.forward(-1 * abs(x1)) p1.goto(x=x2, y=y2) p1.goto(x=x3, y=y2) p1.goto(x=abs(x1)/2, y=0) p1.penup() # 标注长度 p1.goto(x=-20, y=-100) p1.pendown() p1.write(x3 - x2) p1.penup() p1.goto(x=-20, y=-120) p1.pendown() p1.write(abs(x1)) t.mainloop()
关键修改点说明
- 将
nums()和a()的递归逻辑替换为while循环,彻底规避递归深度限制; - 给
x1_solve()增加abs(x1) >22的判断,确保x3_solve()的随机区间有效; - 用
abs(差值) < 阈值的方式判断浮点数近似相等,让终止条件可触发; - 修正变量范围检查的循环条件,明确逻辑优先级。
内容的提问来源于stack exchange,提问作者Fərhad Əhmədov
相关产品推荐
相关产品推荐

