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

Python计时器开发:终端局部清屏,同时显示时间与接收输入

Python计时器问题修复方案

原代码核心问题

  • 用os.system('clear')全清屏幕,导致时间显示和输入界面无法共存
  • asyncio使用逻辑错误:无限递归调用printtime且阻塞后续输入流程
  • 输入未做类型转换与空值处理,直接传入datetime.datetime会触发报错
  • 无效的datetime.datetime(0,0,0,0,0,0)判断,Python不允许年份为0
  • 计时器剩余时间计算逻辑完全错误

关键修复点

  1. 部分清屏实现:使用ANSI转义序列定位光标、清除指定行,只刷新时间区域,保留输入界面
  2. 多线程并行处理:用threading让时间显示在后台线程运行,不阻塞前台用户输入
  3. 输入合法性处理:对空输入填充默认值,字符串转整数并做范围校验
  4. 正确的计时器逻辑:计算目标时间与当前时间的差值,实时显示剩余时长

修正后的完整代码

import time
import datetime
import threading

# 控制时间显示线程的开关
time_running = True

def print_time():
    while time_running:
        # 获取当前日期和时间
        today = datetime.date.today()
        current_time = datetime.datetime.now().strftime("%H : %M : %S")
        # 用ANSI转义序列将光标上移2行,清除行内容后重新打印时间
        print("\033[2A\033[K", end="")
        print(f"The date now is {today}")
        print(f"The time now is {current_time}\033[K")
        time.sleep(1)

def make_timer():
    print("\nSet a predefined timer:")
    # 处理输入,空值设为当前对应时间字段,字符串转整数
    try:
        y = int(input("Set year (leave blank for current): ") or datetime.datetime.now().year)
        m = int(input("Set month (leave blank for current): ") or datetime.datetime.now().month)
        d = int(input("Set day (leave blank for current): ") or datetime.datetime.now().day)
        h = int(input("Set hour (leave blank for current): ") or datetime.datetime.now().hour)
        mt = int(input("Set minute (leave blank for current): ") or datetime.datetime.now().minute)
        s = int(input("Set second (leave blank for current): ") or datetime.datetime.now().second)
    except ValueError:
        print("Error: Please enter valid numbers")
        return make_timer()
    
    try:
        target_time = datetime.datetime(y, m, d, h, mt, s)
    except ValueError:
        print("Error: Invalid date/time")
        return make_timer()
    
    # 检查目标时间是否在未来
    if target_time <= datetime.datetime.now():
        print("Error: Timer must be set to a future time")
        return make_timer()
    
    print(f"Timer set to: {target_time}")
    print("Time remaining:")
    
    # 实时显示剩余时间
    while target_time > datetime.datetime.now():
        remaining = target_time - datetime.datetime.now()
        # 清除当前剩余时间行并打印新值
        print("\033[1A\033[K", end="")
        print(f"{remaining.days} days, {remaining.seconds//3600}h, {(remaining.seconds%3600)//60}m, {remaining.seconds%60}s")
        time.sleep(1)
    
    print("\nTime's up!")

# 启动时间显示后台线程
time_thread = threading.Thread(target=print_time)
time_thread.daemon = True  # 主线程结束时自动退出后台线程
time_thread.start()

# 运行计时器设置逻辑
make_timer()

# 停止时间显示线程
time_running = False

代码说明

  • ANSI转义序列:\033[2A让光标上移2行,\033[K清除光标所在行内容,仅刷新时间区域不干扰输入界面
  • 后台线程:用threading.Thread创建后台线程处理时间刷新,主线程专注输入和计时器逻辑,实现并行操作
  • 输入处理:用or运算符处理空输入,默认使用当前时间对应字段,同时捕获类型错误和无效日期异常
  • 剩余时间计算:通过datetime对象减法得到时间差,实时格式化显示剩余的天、时、分、秒

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 12:12:41