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

使用Python Turtle绘制梯形内同心圆时遇RecursionError:如何修复?

递归深度超限错误的原因及修复方案

错误原因

  1. 无限递归触发深度限制:你的nums()和a()都用递归实现循环尝试,但没有合理的终止条件:
    • a()里用side_1 + side_2 == x3 - x2 + abs(x1)做判断,这是浮点数精确相等比较。由于浮点数计算存在精度误差,两个结果完全相等的概率极低,导致else分支被无限触发,递归调用次数超过Python默认的递归深度(约1000次),抛出RecursionError。
    • nums()的条件判断逻辑有误:and优先级高于or,原条件实际逻辑并非“只要任意变量超出[-150,150]就保留”,可能导致循环递归生成新值,增加触发深度超限的风险。
  2. 参数合法性问题: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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 07:40:02