我该如何延时?

如何在Python脚本中放置时间延迟?

3581494 次浏览

使用time模块中的#0。它可以为亚秒级分辨率采用浮点参数。

from time import sleepsleep(0.1)  # Time in seconds

延迟2.5秒:

import timetime.sleep(2.5)

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

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

与困倦的发生器有点乐趣。

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

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

情况可能是,我们希望尽可能定期地做一些事情,我们不想为代码周围的所有last_timenext_time内容而烦恼。

蜂鸣器发生器

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

import timefrom itertools import count
def buzzergen(period):nexttime = time.time() + periodfor i in count():now = time.time()tosleep = nexttime - nowif tosleep > 0:time.sleep(tosleep)nexttime += periodelse:nexttime = now + periodyield i, nexttime

调用常规buzzergen

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

运行它,我们看到:

1400102636.461400102639.461400102642.461400102647.471400102650.47

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

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

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

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

正如我们所看到的,这个蜂鸣器不是太死板,允许我们赶上规律的睡眠间隔,即使我们睡过头,脱离规律的时间表。

Python标准库中的Tkinter库是一个可以导入的交互式工具。基本上,您可以创建按钮、框、弹出窗口和显示为窗口的东西,您可以使用代码操作它们。

如果你使用Tkinter,不要使用#0,因为它会弄脏你的程序。这发生在我身上。相反,使用root.after()并用毫秒替换多少秒的值。例如,time.sleep(1)等效于Tkinter中的root.after(1000)

否则,time.sleep(),许多答案已经指出,这是要走的路。

延迟是用时间库完成的,特别是#0函数。

让它等待一秒钟:

from time import sleepsleep(1)

这是有效的,因为通过这样做:

from time import sleep

你从时间库中提取睡眠功能只有,这意味着你可以用以下方式调用它:

sleep(seconds)

而不必去打字

time.sleep()

这是笨拙的长类型。

使用此方法,您将无法访问时间库的其他功能,并且您不能拥有名为sleep的变量。但您可以创建一个名为time的变量。

如果你只是想要模块的某些部分,做#0是很棒的。

你也可以这样做:

import timetime.sleep(1)

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

import time as t

这将允许您将时间库引用为t,允许您执行:

t.sleep()

这适用于任何图书馆。

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

在一个线程中,我建议睡眠功能

>>> from time import sleep
>>> sleep(4)

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

将其用于该目的,或者只是延迟函数的执行。例如:

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

“万岁!”在我点击输入后3秒打印。

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

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

为了演示,创建一个这样的脚本(我第一次在交互式Python 3.5 shell中尝试这样做,但子进程由于某种原因找不到party_later函数):

from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor, as_completedfrom 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!
>>>

空行说明该函数打印到我的标准输出,我必须按输入以确保我在提示符上。

这种方法的好处是,当Timer线程等待时,我可以做其他事情,在这种情况下,在函数执行之前点击输入一次(参见第一个空提示符)。

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

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

第一种方法:

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

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

 driver.implicitly_wait(5)

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

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

虽然其他人都建议使用事实上的time模块,但我想我会使用matplotlibpyplot函数#3分享一种不同的方法。

一个例子

from matplotlib import pyplot as pltplt.pause(5)    # Pauses the program for 5 seconds

通常,这用于防止情节在绘制后立即消失或制作粗糙的动画。

如果您已经导入了matplotlib,这将为您节省import

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


time.sleep()示例(如果使用tkinter则不使用):

import timeprint('Hello')time.sleep(5) # Number of secondsprint('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) # Millisecondsprint('Bye')

Matplotlib的函数pyplot.pause()示例(如果您不使用图形,则不推荐,但您可以立即退出图形):

import matplotlibprint('Hello')matplotlib.pyplot.pause(5) # Secondsprint('Bye')

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

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

最后,asyncio.sleep()方法(必须在异步循环中):

await asyncio.sleep(5)

这是一个时间延迟的简单例子:

import time
def delay(period='5'):# If the user enters nothing, it'll wait 5 secondstry:# If the user not enters a int, I'll just return ''time.sleep(period)except:return ''

另一个,在Tkinter

import tkinter
def tick():pass
root = Tk()delay = 100 # Time in millisecondsroot.after(delay, tick)root.mainloop()

asyncio.sleep

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

import asynciofrom datetime import datetime
@asyncio.coroutinedef 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脚本中添加时间延迟:

像这样使用#0#1

from threading import Eventfrom time import sleep
delay_in_sec = 2
# Use time.sleep like thissleep(delay_in_sec)         # Returns Noneprint(f'slept for {delay_in_sec} seconds')
# Or use Event().wait like thisEvent().wait(delay_in_sec)  # Returns Falseprint(f'waited for {delay_in_sec} seconds')

但是,如果您想延迟函数的执行,请执行以下操作:

像这样使用#0

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 parametert.start()  # Returns Noneprint("Started")

产出:

Startedfunction called after 2 seconds

为什么使用后一种方法?

  • 它会没有停止整个脚本的执行(除了传递给它的函数)。
  • 启动计时器后,您也可以通过执行timer_obj.cancel()来停止它。

你也可以试试这个:

import time# The time nowstart = time.time()while time.time() - start < 10: # Run 1- secondspass# Do the job

现在外壳不会崩溃或没有反应。