Python 不中断程序的睡眠

Python 不中断程序的睡眠,python,multithreading,python-3.x,Python,Multithreading,Python 3.x,我正在创建一个在一段时间后倒计时的程序,并要求输入秒数以添加到倒计时中。(不是真的,只是一个例子)。 有点像这样: mytime = 10 while True: print(time) mytime -= 1 time.sleep(1) mytime += int(input('add > ')) 有两个问题 我希望时间在一秒钟后仍然滴答作响,但不想在输入前等待一秒钟。类似我想我需要使用线程 我也不想等待输入!我只想让它在不等待输入的情况下打勾,当我需要时,我可

我正在创建一个在一段时间后倒计时的程序,并要求输入秒数以添加到倒计时中。(不是真的,只是一个例子)。 有点像这样:

mytime = 10
while True:
   print(time)
   mytime -= 1
   time.sleep(1)
   mytime += int(input('add > '))
有两个问题

  • 我希望时间在一秒钟后仍然滴答作响,但不想在输入前等待一秒钟。类似我想我需要使用线程

  • 我也不想等待输入!我只想让它在不等待输入的情况下打勾,当我需要时,我可以输入东西


  • 谢谢您的帮助。

    您需要使用线程来完成此操作。您所要做的就是创建override方法的子类,并在线程上添加一些外部控制方法

    这里是一个简单的例子,你可以尝试和调整根据自己的口味

    import threading
    import time
    
    class SleepingThread(threading.Thread):
    
      def __init__(self, sleep_for):
        super(SleepingThread, self).__init__()
        self.sleep_for = sleep_for
    
      def run(self):
        while self.sleep_for != 0:
          time.sleep(1)
          self.sleep_for -= 1
        print("Done sleeping")
    
      def add_seconds(self, seconds):
        self.sleep_for += seconds
    
      def get_sleep_for(self):
        return self.sleep_for
    
    sleeping_thread = SleepingThread(10)
    sleeping_thread.start()
    while True:
      print(sleeping_thread.get_sleep_for())
      sleeping_thread.add_seconds(int(input('add > ')))
    

    如果你想认真对待它,别忘了。有一种方法比从0创建自己的线程更简单。为您准备的计时器线程:

    import threading
    
    timer = None
    
    def wuf ():
        global timer
        print "Wuf-wuf!"
        timer = threading.Timer(5, wuf)
        timer.start()
    
    timer = threading.Timer(5, wuf)
    timer.start()
    input() # Don't exit the program
    
    此代码将等待5秒,然后每5秒开始打印“Wuf Wuf!”

    如果要从主线程停止,请执行以下操作:

    timer.cancel()
    
    但是,如果您正在使用事件驱动的GUI系统(如wxPython或PyQT)编写GUI应用程序,那么您应该使用它们的事件管理计时器。特别是当您正在从计时器回调更改某些GUI状态时

    编辑: 哦,好吧,这是你的完整答案:

    import threading
    
    seconds = 1 # Initial time must be the time+1 (now 0+1)
    timer = None
    def tick ():
        global seconds, timer
        seconds -= 1
        if seconds==0:
            print("%i seconds left" % seconds)
            print("Timer expired!")
            return
        # printing here will mess up your stdout in conjunction with input()
        print("%i second(s) left" % seconds)
        timer = threading.Timer(1, tick)
        timer.start()
    
    seconds += int(input("Initial countdown interval: "))
    tick()
    while 1:
        seconds += int(input("Add: "))
        if not timer.is_alive():
            print("Restarting the timer!")
            seconds += 1
            tick()
    
    或使用thread的简单版本(但使用threading.thread时会有点笨拙):

    您必须意识到,在线程中使用stdout将在input()输出的提示消息之后插入打印的文本

    这会令人困惑。如果要避免这种情况,那么必须编写另一个线程,从队列中获取消息并输出它们

    如果最后一条消息是提示消息,则必须将其从屏幕中删除,编写新消息,然后返回提示消息,并相应地定位光标


    可以通过在threading.Thread子类中实现类似文件的接口,然后用它替换sys.stdout来实现。可能还会重写input(),以指示何时发出提示消息并读取stdin。

    您肯定需要线程。您调用了可变时间并使用了时间模块。两个相同的名字。哎哟!!!!!!!!!!!这不完全是我想要的。它仍在等待输入,我希望它在每次减少时打印新的时间,而不仅仅是在输入之后。谢谢,但这并不能完全回答我的问题。每次如何调用该程序?我没有看到while True循环。程序没有被调用,函数wuf()是。每一次。Timer()启动一个线程,它启动并等待,在间隔到期后调用给定的函数并停止。函数wuf()设置一个新的计时器(),该计时器将在间隔过期后再次调用。这正是你想要的,你只需要正确地使用它。
    from thread import start_new_thread as thread
    from time import sleep
    
    seconds = 1 # Initial time+1
    alive = 0
    def _tick ():
        global seconds, alive
        try:
            alive = 1
            while 1:
                seconds -= 1
                if seconds==0:
                    print("%i seconds left" % seconds)
                    print("Timer expired!")
                    alive = 0
                    return
                # printing here will mess up your stdout in conjunction with input()
                print("%i second(s) left" % seconds)
                sleep(1)
        except: alive = 0
    
    def tick ():
        thread(_tick,())
    
    # Then same as above:
    seconds += int(input("Initial countdown interval: "))
    tick()
    while 1:
        seconds += int(input("Add: "))
        if not alive:
            print("Restarting the timer!")
            seconds += 1
            tick()