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

音乐测验函数中独立If语句重复执行两次的问题求助

问题分析

你的代码出现重复输出得分的核心原因是递归调用导致多个函数栈实例触发结束逻辑。每次用户猜对/猜错后,你调用了choose_song(),这会让当前的userguess()函数还没执行完,就又启动了新的userguess()实例。当x达到attempts次数时,所有未完成的userguess()栈都会执行最后的结束代码块,所以会重复输出得分和写入文件。

解决方案

要解决这个问题,你需要移除递归调用,改用循环来控制整个测验流程,确保只有当所有尝试次数用完时,才执行一次结束逻辑。具体调整如下:

  1. 把choose_song()的调用从userguess()内部移除,改为在外部控制流程,让主循环负责获取下一首歌曲。
  2. 重构userguess()的逻辑,让它只处理当前歌曲的单次猜测,完成后回到主循环,避免函数栈堆积。
  3. 确保结束逻辑(输出得分、写入文件)只在所有尝试完成后执行一次,而不是每个递归栈都执行。
修改后的完整代码示例
# 假设你已实现Song类和choose_song()基础逻辑
score = 0
x = 0
username = "test_user"
leaderboard = []

def userguess(song):
    global x, score
    # 仅处理当前歌曲的一次猜测
    print(song.firstletters, song.artist)
    guess = str(input("Enter the songs name: "))
    if guess == song.name:
        score += 3
        print("You're correct")
    else:
        print("You're wrong")
    x += 1

# 主流程控制函数
def run_quiz(total_attempts):
    global x, score
    while x < total_attempts:
        current_song = choose_song()  # 获取下一首要猜的歌曲
        userguess(current_song)
    # 所有尝试完成后,执行一次结束逻辑
    print("You scored: ", score)
    # 用with语句自动管理文件,避免资源泄漏
    with open("leaderboard.txt", "a") as g:
        g.write(f"{username},{score},")
    print(leaderboard)

# 启动测验(示例:设置2次尝试)
run_quiz(2)
关键调整点说明
  • 移除递归调用:将choose_song()移到主循环run_quiz()中,每次完成单次猜测后,主循环负责获取下一首歌曲,避免多个userguess()实例堆积。
  • 文件操作优化:使用with语句自动处理文件的打开和关闭,同时用f-string简化用户名和分数的写入格式,避免零散的write调用。
  • 单一结束逻辑:结束代码块只在主循环退出后执行一次,彻底解决重复输出和重复写入的问题。

内容的提问来源于stack exchange,提问作者King

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 05:32:32