【发布时间】:2010-09-09 00:46:35
【问题描述】:
我想知道如何在 Python 脚本中设置时间延迟。
【问题讨论】:
标签: python python-3.x delay sleep timedelay
我想知道如何在 Python 脚本中设置时间延迟。
【问题讨论】:
标签: python python-3.x delay sleep timedelay
您可以使用sleep() function in the time module。它可以采用浮点参数进行亚秒级分辨率。
from time import sleep
sleep(0.1) # Time in seconds
【讨论】:
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).
【讨论】:
困倦的generator有点乐趣。
问题是关于时间延迟的。它可以是固定时间,但在某些情况下,我们可能需要测量自上次以来的延迟。这是一种可能的解决方案:
情况可能是,我们希望尽可能有规律地做某事,我们不想为代码周围的所有last_time、next_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
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)
正如我们所看到的,这个蜂鸣器并不太死板,即使我们睡过头并超出了正常的日程安排,也能让我们赶上规律的困倦时间。
【讨论】:
Python 标准库中的Tkinter 库是一个可以导入的交互式工具。基本上,您可以创建按钮和框以及弹出窗口和显示为您使用代码操作的窗口的东西。
如果你使用 Tkinter,不要使用time.sleep(),因为它会破坏你的程序。这发生在我身上。相反,使用root.after() 并将值替换为多少秒,以毫秒为单位。例如,time.sleep(1) 等价于 Tkinter 中的 root.after(1000)。
否则,time.sleep(),很多答案都指出了,这是要走的路。
【讨论】:
延迟是通过time library 完成的,特别是time.sleep() 函数。
让它等待一秒钟:
from time import sleep
sleep(1)
这是有效的,因为这样做:
from time import sleep
您从time library 中提取sleep function only,这意味着您可以通过以下方式调用它:
sleep(seconds)
不必打字
time.sleep()
打字太长了。
使用此方法,您将无法访问time library 的其他功能,并且您无法拥有名为sleep 的变量。但是您可以创建一个名为 time 的变量。
如果您只想要模块的某些部分,则使用from [library] import [function] (, [function2]) 非常棒。
你也可以这样做:
import time
time.sleep(1)
只要您键入time.[function](),您就可以访问time library 的其他功能,例如time.clock(),但您无法创建变量时间,因为它会覆盖导入。解决这个问题的方法
import time as t
这将允许您将time library 引用为t,允许您执行以下操作:
t.sleep()
这适用于任何库。
【讨论】:
time.sleep()”
如何在 Python 中进行时间延迟?
在一个线程中我建议sleep function:
>>> 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 threading 对象触发稍后在单独线程中调用的函数:
>>> from threading import Timer
>>> t = Timer(3, party_time, args=None, kwargs=None)
>>> t.start()
>>>
>>> hooray!
>>>
空白行说明该函数打印到我的标准输出,我必须按 Enter 以确保我在提示符下。
这种方法的好处是,当Timer 线程在等待时,我可以做其他事情,在这种情况下,在函数执行之前按一次 Enter(参见第一个空提示)。
multiprocessing library 中没有相应的对象。您可以创建一个,但它可能由于某种原因不存在。对于一个简单的计时器来说,一个子线程比一个全新的子进程更有意义。
【讨论】:
延迟也可以通过以下方法实现。
第一种方法:
import time
time.sleep(5) # Delay for 5 seconds.
第二种延迟方法是使用隐式等待方法:
driver.implicitly_wait(5)
当您必须等到特定操作完成或找到元素时,第三种方法更有用:
self.wait.until(EC.presence_of_element_located((By.ID, 'UserName'))
【讨论】:
虽然其他人都建议使用事实上的time 模块,但我想我会使用matplotlib 的pyplot 函数pause 分享不同的方法。
from matplotlib import pyplot as plt
plt.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 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')
最后,asyncio.sleep() 方法:
import asyncio
asyncio.sleep(5)
【讨论】:
driver.implicitly_wait() 是一个 selenium webdriver 方法,用于设置在网页上查找元素的默认等待时间。这与提出的问题完全无关。
这是一个简单的时间延迟示例:
import time
def delay(period='5'):
# If the user enters nothing, it'll wait 5 seconds
try:
# 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 milliseconds
root.after(delay, tick)
root.mainloop()
【讨论】:
请注意,在最近的 Python 版本(Python 3.4 或更高版本)中,您可以使用 asyncio.sleep。它与异步编程和asyncio有关。查看下一个示例:
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 official documentation了解更多详情。
【讨论】:
time.sleep 运行类似的示例。您不会得到相同的运行时间结果。推荐阅读asynchronouspython编程
像这样使用 time.sleep 或 Event().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() 停止它。【讨论】:
你也可以试试这个:
import time
# The time now
start = time.time()
while time.time() - start < 10: # Run 1- seconds
pass
# Do the job
现在外壳不会崩溃或没有反应。
【讨论】: