如何在代码中添加延迟

本指南将详细介绍如何在 Python 中利用内置的 time 模块中的 sleep() 函数,为您的代码添加时间延迟效果。

在执行一个 Python 程序时,代码通常会按照语句的先后顺序逐条执行,没有任何停顿。 但是,有时您可能需要在代码的执行过程中引入延迟。 Python 的内置 time 模块提供的 sleep() 函数可以满足这个需求。

在本教程中,您将学习 sleep() 函数的语法,并结合多个示例来深入理解它的工作原理。 让我们开始吧!

Python 中 time.sleep() 的语法

Python 标准库中的 time 模块提供了许多与时间操作相关的实用函数。 首先,您需要将 time 模块导入到您的工作环境中:

import time

因为 sleep() 函数是 time 模块的一部分,您可以通过以下标准语法来访问并使用它:

time.sleep(n)

这里的 n 代表需要睡眠的秒数。 它可以是一个整数,也可以是一个浮点数。

有些时候,所需的延迟可能仅为几毫秒。 在这种情况下,您可以将毫秒转换为秒,然后在调用 sleep() 函数时使用。 例如,如果需要 100 毫秒的延迟,可以将其表示为 0.1 秒: time.sleep(0.1)

或者,您也可以直接从 time 模块导入 sleep 函数:

from time import sleep

如果使用这种方式导入,您可以直接调用 sleep() 函数,而无需使用 time.sleep()

现在您已经掌握了 sleep() 函数的语法,接下来通过一些示例代码来演示它的实际应用。 您可以从 GitHub 仓库的 python-sleep 文件夹中下载本教程所使用的 Python 脚本。 👩🏽‍💻

使用 sleep() 函数延迟代码执行

首先,让我们使用 sleep() 函数来延迟执行一个简单的 Python 程序。

在以下代码片段中:

  • 第一个 print() 语句会立即执行。
  • 接着,我们使用 sleep() 函数引入一个 5 秒的延迟。
  • 第二个 print() 语句会在睡眠操作完成后才会执行。
    
# /python-sleep/simple_example.py
import time

print("Print now")
time.sleep(5)
print("Print after sleeping for 5 seconds")
    

现在运行 simple_example.py 文件,观察输出结果:

$ python3 simple_example.py

在代码块中添加不同的延迟

在前面的例子中,我们在两个 print() 语句之间添加了一个 5 秒的固定延迟。 接下来,我们编写另一个示例,实现在循环遍历可迭代对象时引入不同的延迟时间。

在这个例子中,我们将执行以下操作:

  • 遍历一个句子,访问其中的每一个单词并打印出来。
  • 打印完每个单词后,我们希望等待一段时间,然后再打印出句子中的下一个单词。

循环遍历字符串中的字符

我们把句子看作一个字符串,句子中的每个单词也都是字符串。

如果我们直接遍历这个字符串,我们会得到每个字符,如下所示:

    
>>> sentence = "How long will this take?"
>>> for char in sentence:
...     print(char)

# 输出(为方便阅读已截断)
H
o
w
.
.
.
t
a
k
e
?
    

但这并不是我们想要的效果。 我们希望遍历句子并访问每个单词。 为了实现这个目标,我们可以在句子字符串上调用 split() 方法。 这将返回一个字符串列表,列表中的元素是通过空格分割句子字符串得到的。

    
>>> sentence.split()
['How', 'long', 'will', 'this', 'take?']
>>> for word in sentence.split():
...     print(word)

# 输出
How
long
will
this
take?
    

循环遍历具有不同延迟的可迭代对象

让我们回到之前的示例:

  • sentence 是我们需要循环访问的字符串,每次访问一个单词。
  • delay_times 是一个延迟时间列表,我们将在每次循环中使用它作为 sleep() 函数的参数。

这里,我们希望同时遍历两个列表:delay_times 列表和通过分割句子字符串得到的字符串列表。 可以使用 zip() 函数实现这种并行遍历。

Python 的 zip() 函数:zip(list1, list2) 返回一个元组的迭代器,其中每个元组包含 list1list2 中索引为 i 的元素。

    
# /python-sleep/delay_times.py
import time

sleep_times = [3,4,1.5,2,0.75]
sentence = "How long will this take?"
for sleep_time,word in zip(sleep_times,sentence.split()):
    print(word)
    time.sleep(sleep_time)
    

如果没有 sleep() 函数,控制流将立即跳转到下一次迭代。 由于我们引入了延迟,只有在睡眠操作完成之后,下一次循环才会发生。

现在运行 delay_times.py 并观察输出:

$ python3 delay_times.py

字符串中后续的单词将在相应的延迟之后打印出来。 打印字符串中索引为 i 的单词之后的延迟,对应于 delay_times 列表中索引为 i 的数字。

使用 Python 创建倒计时器

接下来,让我们用 Python 编写一个简单的倒计时器。

我们定义一个名为 countDown() 的函数:

    
# /python-sleep/countdown.py
import time

def countDown(n):
    for i in range(n,-1,-1):
        if i==0:
            print("Ready to go!")
        else:
             print(i)
             time.sleep(1)
    

接下来,我们分析一下 countDown() 函数的定义:

  • 该函数接收一个数字 n 作为参数,并从 n 开始倒数到零。
  • 我们使用 time.sleep(1) 在每次计数之间实现一秒的延迟。
  • 当计数达到 0 时,函数输出 “Ready to go!”。

🎯 为了实现倒计时功能,我们使用了步长为 -1 的 range() 函数。 range(n, -1, -1) 将帮助我们遍历从 n 到 0 的数字序列。 请记住,使用 range() 函数时,终点默认是不包含在内的。

接下来,我们使用参数 5 调用 countDown() 函数。

countDown(5)

现在运行 countdown.py 脚本,看看 countDown() 函数是如何工作的!

$ python3 countdown.py

多线程中的 sleep() 函数

Python 的 threading 模块提供了多线程的功能。 在 Python 中,全局解释器锁(GIL)确保在任何时刻只有一个线程在执行。

然而,在执行 I/O 操作和睡眠等等待操作期间,处理器可以暂停当前线程的执行,切换到另一个等待执行的线程。

为了理解这是如何工作的,让我们看一个例子。

在 Python 中创建和运行线程

考虑以下函数 func1()func2()func3()。 它们分别循环遍历一系列数字并将其打印出来,并在每次循环迭代中加入睡眠操作,持续特定的秒数。 我们为每个函数使用了不同的延迟时间,以便更好地理解线程之间是如何并发切换的。

    
import time

def func1():
    for i in range(5):
        print(f"Running t1, print {i}.")
        time.sleep(2)

def func2():
    for i  in range(5):
         print(f"Running t2, print {i}.")
         time.sleep(1)


def func3():
    for i in range(4):
         print(f"Running t3, print {i}.")
         time.sleep(0.5)
    

在 Python 中,您可以使用 Thread() 构造函数来实例化线程对象。 使用 threading.Thread(target = …, args = …) 的语法创建一个线程,该线程将使用 args 元组中指定的参数来运行目标函数。

在这个例子中,函数 func1func2func3 不接受任何参数。 因此,只需将函数名称指定为目标即可。 然后,我们分别以 func1func2func3 为目标定义线程对象 t1t2t3

    
t1 = threading.Thread(target=func1)
t2 = threading.Thread(target=func2)
t3 = threading.Thread(target=func3)

t1.start()
t2.start()
t3.start()
    

以下是线程示例的完整代码:

    
# /python-sleep/threads.py
import time
import threading

def func1():
    for i in range(5):
        print(f"Running t1, print {i}.")
        time.sleep(2)

def func2():
    for i  in range(5):
         print(f"Running t2, print {i}.")
         time.sleep(1)

def func3():
    for i in range(4):
         print(f"Running t3, print {i}.")
         time.sleep(0.5)

t1 = threading.Thread(target=func1)
t2 = threading.Thread(target=func2)
t3 = threading.Thread(target=func3)

t1.start()
t2.start()
t3.start()
    

观察输出。 执行在三个线程之间切换。 线程 t3 的等待时间最短,因此挂起的时间也最短。 线程 t1 的睡眠持续时间最长,为 2 秒,因此它是最后一个完成执行的线程。

要了解更多信息,请阅读关于 Python 多线程基础的教程。

总结

在本教程中,您学习了如何使用 Python 的 sleep() 函数为代码添加时间延迟。

您可以通过内置的 time 模块中的 time.sleep() 访问 sleep() 函数。 要将执行延迟 n 秒,请使用 time.sleep(n)。 此外,您还看到了通过不同值、倒计时和多线程来延迟循环中后续迭代的示例。

您现在可以探索 time 模块的更多高级功能。 是否想在 Python 中处理日期和时间? 除了 time 模块之外,您还可以使用 datetimecalendar 模块的功能。

接下来,学习如何在 Python 中计算时间差。⏰