如何实现计时器与Python代码并行运行?解决my_timer未定义问题
问题解决与代码重构
错误原因
my_timer未定义:主线程启动倒计时线程后立刻访问该变量,但线程可能还未完成初始化;同时原代码存在严重缩进错误,countdown函数内的初始化逻辑未被正确执行。- 计时器逻辑错误:全局单线程无法实现每道题独立的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
相关产品推荐
相关产品推荐

