MST

星途 面试题库

面试题:Python中协程与普通函数的主要区别

请详细阐述Python中协程与普通函数在执行过程、资源占用、调用方式等方面的主要区别。
17.2万 热度难度
编程语言Python

知识考点

AI 面试

面试题答案

一键面试

执行过程

  • 普通函数:顺序执行,从函数开头执行到结尾,调用者等待函数执行完毕返回结果后才继续执行后续代码。函数执行过程中,遇到函数调用就暂停当前函数执行,转去执行被调用函数,被调用函数执行完返回结果,再继续执行原函数。例如:
def func1():
    print("开始执行func1")
    result = func2()
    print("func1继续执行,func2返回结果:", result)
    return "func1执行完毕"

def func2():
    print("开始执行func2")
    return "func2执行完毕"

func1()
  • 协程:可以暂停执行并将执行权交回给调用者,之后又能从暂停的地方继续执行。协程使用 yield 关键字暂停执行并返回值,使用 send 方法向暂停的协程传入值并恢复执行。例如:
def simple_coroutine():
    print('-> 协程启动')
    x = yield
    print('-> 协程接收值:', x)

my_coro = simple_coroutine()
next(my_coro)
my_coro.send(42)

资源占用

  • 普通函数:在执行过程中,会一直占用栈空间等资源,直到函数执行完毕释放资源。如果函数调用层级过深,容易导致栈溢出。例如,一个递归函数如果没有正确的终止条件,不断调用自身,栈空间会不断被占用,最终导致栈溢出错误。
def infinite_recursion():
    infinite_recursion()
  • 协程:不需要像普通函数那样维护完整的调用栈,在暂停时可以释放部分资源,所以在资源占用上更加轻量级。多个协程可以在一个线程内交替执行,避免了线程切换带来的开销。

调用方式

  • 普通函数:通过函数名加括号,传递参数的方式调用,调用后程序控制权转移到被调用函数,直到被调用函数返回,控制权才回到调用处。例如:result = func(a, b)func 是普通函数,ab 是参数。
  • 协程:需要先创建协程对象,通常使用 next() 函数或者 send(None) 启动协程,使其运行到第一个 yield 处暂停。之后可以使用 send() 方法向协程传递数据并使其从暂停处继续执行。例如:
def coroutine():
    value = yield
    return value

my_coro = coroutine()
next(my_coro)
result = my_coro.send(10)