如何在 Python 中进行时间延迟?

我想知道如何在 Python 脚本中放置时间延迟。

答案

import time
time.sleep(5)   # Delays for 5 seconds. You can also use a float value.

这是另一个示例,其中某件事大约每分钟运行一次:

import time
while True:
    print("This prints once a minute.")
    time.sleep(60) # Delay for 1 minute (60 seconds).

您可以time模块中使用sleep()函数 。对于亚秒级分辨率,它可以采用 float 参数。

from time import sleep
sleep(0.1) # Time in seconds

如何在 Python 中进行时间延迟?

在一个线程中,我建议使用sleep 函数

>>> from time import sleep

>>> sleep(4)

该函数实际上挂起了操作系统在其中调用它的线程的处理,从而允许其他线程和进程在其休眠时执行。

为此,可以使用它,也可以只是延迟执行功能。例如:

>>> def party_time():
...     print('hooray!')
...
>>> sleep(3); party_time()
hooray!

“万岁!” 在我按 Enter 键 3 秒后打印出来。

使用具有多个线程和进程的sleep示例

同样, sleep挂起您的线程 - 它使用接近零的处理能力。

为了演示,创建一个这样的脚本(我首先在交互式 Python 3.5 shell 中尝试过此操作,但是由于某些原因子进程找不到party_later函数):

from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor, as_completed
from time import sleep, time

def party_later(kind='', n=''):
    sleep(3)
    return kind + n + ' party time!: ' + __name__

def main():
    with ProcessPoolExecutor() as proc_executor:
        with ThreadPoolExecutor() as thread_executor:
            start_time = time()
            proc_future1 = proc_executor.submit(party_later, kind='proc', n='1')
            proc_future2 = proc_executor.submit(party_later, kind='proc', n='2')
            thread_future1 = thread_executor.submit(party_later, kind='thread', n='1')
            thread_future2 = thread_executor.submit(party_later, kind='thread', n='2')
            for f in as_completed([
              proc_future1, proc_future2, thread_future1, thread_future2,]):
                print(f.result())
            end_time = time()
    print('total time to execute four 3-sec functions:', end_time - start_time)

if __name__ == '__main__':
    main()

该脚本的示例输出:

thread1 party time!: __main__
thread2 party time!: __main__
proc1 party time!: __mp_main__
proc2 party time!: __mp_main__
total time to execute four 3-sec functions: 3.4519670009613037

多线程

您可以触发稍后在另一个线程中使用Timer 线程对象的函数:

>>> from threading import Timer
>>> t = Timer(3, party_time, args=None, kwargs=None)
>>> t.start()
>>>
>>> hooray!

>>>

空行说明该函数已打印到我的标准输出中,我必须按Enter 键以确保出现提示。

这种方法的好处是,在Timer线程等待期间,我可以执行其他操作,在这种情况下,在执行函数之前,请按Enter 键一次(请参阅第一个空提示)。

多处理库中没有相应的对象。您可以创建一个,但是由于某种原因它可能不存在。对于一个简单的计时器来说,子线程比一个全新的子进程更有意义。

昏昏欲睡的发电机有点乐趣。

问题是时间延迟。它可以是固定的时间,但是在某些情况下,我们可能需要自上次以来算起延迟时间。这是一种可能的解决方案:

自上次测量的延迟(定期唤醒)

情况可能是,我们希望尽可能定期地执行某些操作,并且不想在我们的代码中打扰所有last_timenext_time东西。

蜂鸣器发生器

以下代码( sleepy.py )定义了一个buzzergen生成器:

import time
from itertools import count

def buzzergen(period):
    nexttime = time.time() + period
    for i in count():
        now = time.time()
        tosleep = nexttime - now
        if tosleep > 0:
            time.sleep(tosleep)
            nexttime += period
        else:
            nexttime = now + period
        yield i, nexttime

调用常规的 Buzzergen

from sleepy import buzzergen
import time
buzzer = buzzergen(3) # Planning to wake up each 3 seconds
print time.time()
buzzer.next()
print time.time()
time.sleep(2)
buzzer.next()
print time.time()
time.sleep(5) # Sleeping a bit longer than usually
buzzer.next()
print time.time()
buzzer.next()
print time.time()

运行它,我们看到:

1400102636.46
1400102639.46
1400102642.46
1400102647.47
1400102650.47

我们也可以直接在循环中使用它:

import random
for ring in buzzergen(3):
    print "now", time.time()
    print "ring", ring
    time.sleep(random.choice([0, 2, 4, 6]))

运行它,我们可能会看到:

now 1400102751.46
ring (0, 1400102754.461676)
now 1400102754.46
ring (1, 1400102757.461676)
now 1400102757.46
ring (2, 1400102760.461676)
now 1400102760.46
ring (3, 1400102763.461676)
now 1400102766.47
ring (4, 1400102769.47115)
now 1400102769.47
ring (5, 1400102772.47115)
now 1400102772.47
ring (6, 1400102775.47115)
now 1400102775.47
ring (7, 1400102778.47115)

正如我们所看到的,该蜂鸣器不是太僵硬,即使我们睡过头并超出了常规时间表,也可以让我们按规律地困倦。

延迟也可以通过以下方法实现。

第一种方法:

import time
time.sleep(5) # Delay for 5 seconds.

第二种延迟方法是使用隐式等待方法:

driver.implicitly_wait(5)

当您必须等待完成特定操作或找到元素时,第三种方法更有用:

self.wait.until(EC.presence_of_element_located((By.ID, 'UserName'))

Python 标准库中的Tkinter库是一个可以导入的交互式工具。基本上,您可以创建按钮,框,弹出式窗口以及显示为窗口的内容,并使用代码进行操作。

如果您使用 Tkinter, 请不要使用time.sleep() ,因为它会破坏您的程序。这发生在我身上。而是使用root.after()并将值替换很多秒(以毫秒为单位)。例如, root.after(1000) time.sleep(1)等同于 Tkinter 中的root.after(1000)

否则,很多答案都指出了time.sleep() ,这是要走的路。

延迟是通过时间库完成的,特别是time.sleep()函数。

只需等待一秒钟:

from time import sleep
sleep(1)

之所以有效,是因为通过执行以下操作:

from time import sleep

只能时间库中提取sleep 函数 ,这意味着您可以使用以下命令进行调用:

sleep(seconds)

无需输入

time.sleep()

很难输入。

使用这种方法,您将无法访问时间库的其他功能,也无法获得名为sleep的变量。但是您可以创建一个名为time的变量。

如果只需要模块的某些部分,则可以from [library] import [function] (, [function2])

您同样可以这样做:

import time
time.sleep(1)

并且只要键入time.[function]() ,您就可以访问时间库的其他功能,例如time.clock() time.[function]() ,但是您无法创建可变时间,因为它会覆盖导入。解决方案

import time as t

这将允许您将时间库引用为t ,从而可以执行以下操作:

t.sleep()

这适用于任何库。

有五种方法,我知道: time.sleep() pygame.time.wait() ,matplotlib 的pyplot.pause() .after()driver.implicitly_wait()


time.sleep()示例(如果使用Tkinter,则不要使用):

import time
print('Hello')
time.sleep(5) # Number of seconds
print('Bye')

pygame.time.wait()示例(如果不使用Pygame窗口,则不建议使用,但可以立即退出该窗口):

import pygame
# If you are going to use the time module
# don't do "from pygame import *"
pygame.init()
print('Hello')
pygame.time.wait(5000) # Milliseconds
print('Bye')

matplotlib 的函数pyplot.pause()示例(如果不使用图形,则不建议使用,但可以立即退出图形):

import matplotlib
print('Hello')
matplotlib.pyplot.pause(5) # Seconds
print('Bye')

.after()方法(Tkinter 最好):

import tkinter as tk # Tkinter for Python 2
root = tk.Tk()
print('Hello')
def ohhi():
    print('Oh, hi!')
root.after(5000, ohhi) # Milliseconds and then a function
print('Bye')

最后,使用driver.implicitly_wait()方法( Selenium ):

driver.implicitly_wait(5) # Waits 5 seconds

异步睡眠

请注意,在最新的 Python 版本(Python 3.4 或更高版本)中,您可以使用asyncio.sleep 。它与异步编程和异步有关。查看下一个示例:

import asyncio
from datetime import datetime

@asyncio.coroutine
def countdown(iteration_name, countdown_sec):
    """
    Just count for some countdown_sec seconds and do nothing else
    """
    while countdown_sec > 0:
       print(f'{iteration_name} iterates: {countdown_sec} seconds')
       yield from asyncio.sleep(1)
       countdown_sec -= 1

loop = asyncio.get_event_loop()
tasks = [asyncio.ensure_future(countdown('First Count', 2)),
         asyncio.ensure_future(countdown('Second Count', 3))]

start_time = datetime.utcnow()

# Run both methods. How much time will both run...?
loop.run_until_complete(asyncio.wait(tasks))

loop.close()

print(f'total running time: {datetime.utcnow() - start_time}')

我们可能认为第一种方法将 “休眠” 2 秒,第二种方法将 “休眠” 3 秒,这段代码的运行时间总计为 5 秒。但是它将打印:

total_running_time: 0:00:03.01286

建议阅读asyncio 官方文档以了解更多详细信息。

如果您想在 Python 脚本中添加时间延迟:

使用time.sleepEvent().wait像这样:

from threading import Event
from time import sleep

delay_in_sec = 2

# Use time.sleep like this
sleep(delay_in_sec)         # Returns None
print(f'slept for {delay_in_sec} seconds')

# Or use Event().wait like this
Event().wait(delay_in_sec)  # Returns False
print(f'waited for {delay_in_sec} seconds')

但是,如果要延迟执行功能,请执行以下操作:

像这样使用threading.Timer

from threading import Timer

delay_in_sec = 2

def hello(delay_in_sec):
    print(f'function called after {delay_in_sec} seconds')

t = Timer(delay_in_sec, hello, [delay_in_sec])  # Hello function will be called 2 seconds later with [delay_in_sec] as the *args parameter
t.start()  # Returns None
print("Started")

输出:

Started
function called after 2 seconds

为什么要使用后一种方法?

  • 不会停止整个脚本的执行(除非你通过它的功能)。
  • 启动计时器后,您也可以通过执行timer_obj.cancel()来停止计时器。