为Python测验添加th.Timer计时器失败,请求问题排查
解决测验程序计时器失效问题
核心问题分析
你的代码里启动计时器后立刻调用了S.cancel(),直接终止了计时器,导致它根本没机会完成20秒计时。而且show_questions执行时计时器已经被取消,后续判断S.is_alive()永远为False,完全起不到超时校验的作用。
修复方案
需要调整逻辑,让计时器在用户答题过程中后台运行,直到用户提交答案(此时取消计时器)或超时触发动作。具体步骤如下:
- 设置超时状态标记:用可变对象(比如列表)存储超时状态,让计时器线程能修改这个状态(线程无法直接修改全局不可变变量)。
- 完善超时处理函数:让
sctn函数在超时触发时标记超时状态,并给出提示。 - 调整答题流程:启动计时器后等待用户输入答案,输入完成后先检查是否超时,再决定后续逻辑。
修改后的代码示例
import threading as th import random import json # 初始化全局变量 points = 0 total_points = 0 the_filenames = ["section1.json", "section2.json"] # 示例文件名 def show_questions(question): # 模拟展示题目并获取用户输入 print(f"题目:{question['pytanie']}") print(f"选项:{question['odpowiedzi']}") return input("请输入你的答案:") def sctn(timeout_flag): # 超时触发的动作:标记超时并提示 timeout_flag[0] = True print("\n时间到!未在规定时间内提交答案") while True: if len(the_filenames) == 0: print("所有题目已完成!") break random_section = random.choice(the_filenames) print(f"\nWylosowano dział: {random_section[:-5]}") with open(f"C:\\Users\\Tymek\\PycharmProjects\\pythonProject1\\quiz!\\ematyka\\{random_section}") as file: questions = json.load(file) the_filenames.remove(random_section) for question in questions: timeout_flag = [False] # 每次答题重置超时标记 # 启动20秒计时器,传入超时标记 S = th.Timer(20, sctn, args=(timeout_flag,)) S.start() # 获取用户答案 answer = show_questions(question) # 先检查是否超时 if timeout_flag[0]: total_points += 1 print(f"Twój aktualny wynik to: {points} / {total_points}") continue # 超时直接进入下一题 # 未超时则取消计时器,判断答案 S.cancel() if answer == question["prawidlowa_odpowiedz"]: points += 1 total_points += 1 print(f"Brawo, prawidłowa odpowiedź, twój aktualny wynik: {points} / {total_points} punktów") else: total_points += 1 print(f"Zła odpowiedź, twój aktualny wynik: {points} / {total_points} punktów") print(f"Twój aktualny wynik to: {points} / {total_points}")
关键修改说明
- 用
timeout_flag = [False]传递超时状态:列表是可变对象,计时器线程可以修改其内部值,主线程能实时读取状态。 - 启动计时器后先等待用户输入答案:不再立刻取消计时器,只有当用户在超时前提交答案,才调用
S.cancel()终止计时器。 - 优先判断超时状态:如果超时,直接计入总分不加分,跳过答案判断流程。
内容的提问来源于stack exchange,提问作者Tymek Stawarz
相关产品推荐
相关产品推荐

