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

如何实现计时器与Python代码并行运行?解决my_timer未定义问题

问题解决与代码重构

错误原因

  1. my_timer未定义:主线程启动倒计时线程后立刻访问该变量,但线程可能还未完成初始化;同时原代码存在严重缩进错误,countdown函数内的初始化逻辑未被正确执行。
  2. 计时器逻辑错误:全局单线程无法实现每道题独立的5秒倒计时,且原代码的循环逻辑混乱,无法正确触发超时提示。

修正后的完整代码

import time
import threading
import random

# 定义常量与数据
guess_elements = ["Hydrogen", "Magnesium", "Cobalt", "Mercury", "Aluminium", "Uranium", "Antimony"]
nice_phrases = ["Nice job", "Marvellous", "Wonderful", "Bingo", "Dynamite"]
wrong_answers = ["Wrong answer...", "Nope", "Try again next time.", "Wrong answer. Nice effort"]
score = 0

# 元素提示字典,统一管理避免重复代码
element_tips = {
    "Hydrogen": [
        "Tip 1: It is the most flammable of all the known substances.",
        "Tip 2: It reacts with oxides and chlorides of many metals, like copper, lead, mercury, to produce free metals.",
        "Tip 3: It reacts with oxygen to form water."
    ],
    "Magnesium": [
        "Tip 1: It has the atomic number of 12.",
        "Tip 2: It's oxide can be extracted into free metal through electrolysis.",
        "Tip 3: It is a type of metal."
    ],
    "Cobalt": [
        "Tip 1: Atomic number 27.",
        "Tip 2: Used in rechargeable batteries.",
        "Tip 3: A hard, lustrous, silver-gray metal."
    ],
    "Mercury": [
        "Tip 1: Only metal that's liquid at room temperature.",
        "Tip 2: Atomic number 80.",
        "Tip 3: Formerly used in thermometers."
    ],
    "Aluminium": [
        "Tip 1: Atomic number 13.",
        "Tip 2: Lightweight and corrosion-resistant.",
        "Tip 3: The most abundant metal in Earth's crust."
    ],
    "Uranium": [
        "Tip 1: Atomic number 92.",
        "Tip 2: Used as fuel in nuclear reactors.",
        "Tip 3: A radioactive element."
    ],
    "Antimony": [
        "Tip 1: Atomic number 51.",
        "Tip 2: Used in flame retardants.",
        "Tip 3: A metalloid."
    ]
}

def countdown(timeout, timeout_event):
    """独立倒计时线程,超时后触发事件标记"""
    for _ in range(timeout):
        time.sleep(1)
        # 如果用户已完成答题,提前终止倒计时
        if timeout_event.is_set():
            return
    # 时间到,触发超时并提示
    timeout_event.set()
    print("\nOut of time.Haiya!")

def handle_element(element):
    """处理单道题的答题流程"""
    global score
    guess_count = 0
    guess_limit = 3
    out_of_guesses = False
    guess = ""

    # 初始化超时事件,用于线程间同步
    timeout_event = threading.Event()
    # 启动倒计时线程,设置为守护线程避免残留
    timer_thread = threading.Thread(target=countdown, args=(5, timeout_event))
    timer_thread.daemon = True
    timer_thread.start()

    # 打印当前元素的提示
    for tip in element_tips[element]:
        print(tip)

    # 答题循环:同时检查超时、答题次数、是否答对
    while guess != element and not out_of_guesses and not timeout_event.is_set():
        if guess_count < guess_limit:
            guess = input("Enter guess: ").strip()
            guess_count += 1
        else:
            out_of_guesses = True

    # 处理答题结果
    if timeout_event.is_set():
        print(f"The correct element was {element}.")
    elif out_of_guesses:
        print(random.choice(wrong_answers))
        print(f"The correct element was {element}.")
    else:
        print(random.choice(nice_phrases), ", YOU GET IT!")
        score += 1

def main():
    # 打乱元素顺序,随机出题
    random.shuffle(guess_elements)
    for element in guess_elements:
        print(f"\n--- New Question ---")
        handle_element(element)
        time.sleep(1)
    # 显示最终得分
    print(f"\nFinal Score: {score}/{len(guess_elements)}")

if __name__ == "__main__":
    main()

关键改进点

  • 用threading.Event()替代全局变量,安全实现线程间的超时状态同步,避免竞态条件。
  • 每道题启动独立的倒计时线程,满足"每道题5秒倒计时"的需求。
  • 封装答题逻辑为函数,用字典管理元素提示,大幅减少重复代码,提升可维护性。
  • 设置守护线程,确保主线程结束时自动清理计时器线程,避免资源残留。
  • 修复原代码的缩进错误,理清逻辑流程,确保代码可正常运行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 04:40:35