You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python异步等待函数传入布尔变量后while循环条件无法更新的问题

Python异步等待函数传入布尔变量后while循环条件无法更新的问题

嗨,我来帮你捋清楚这个问题~

你遇到的情况本质上是Python里不可变类型的参数传递特性导致的:像布尔值、整数、字符串这类不可变类型,当你把它们作为参数传给函数时,传递的是当前值的一份拷贝,而不是指向原变量的“指针”或者引用。

你看,当你调用wait_for(action_done)的时候,action_to_wait拿到的是action_done当时的False值,之后哪怕function_A把全局的action_done改成了True,wait_for里的action_to_wait还是原来的False拷贝,所以那个while循环会一直跑下去,永远不会终止。而wait_for_action_to_be_done()是直接读取全局的action_done,每次循环都会去拿最新的值,所以能正常工作。

那怎么解决这个问题呢?给你两种常用的方案:

方案一:用可变容器包裹布尔值

既然不可变类型传的是值拷贝,那我们可以用一个可变的容器(比如列表)来装这个布尔值,这样传递的是容器的引用,修改容器里的元素时,函数内部能看到变化:

import asyncio

action_done = [False]  # 用列表包裹布尔值

async def function_A(delay):
    global action_done
    await asyncio.sleep(delay)
    action_done[0] = True  # 修改列表里的元素

async def wait_for(action_to_wait):
    print("wait for action to be done...")
    while not action_to_wait[0]:  # 检查列表里的元素
        await asyncio.sleep(0.1)

async def function_B():
    await wait_for(action_done)
    print("performing next action...")

async def main():
    await asyncio.gather(function_A(2), function_B())

asyncio.run(main())

方案二:用asyncio.Event(更推荐的异步同步方式)

其实在Python异步编程里,有专门的同步原语来处理这种“等待某个动作完成”的场景,那就是asyncio.Event,它比自己写while轮询更高效,也更符合异步编程的规范,还能避免全局变量带来的潜在问题:

import asyncio

async def function_A(delay, event):
    await asyncio.sleep(delay)
    event.set()  # 触发事件,标记动作完成

async def wait_for(event):
    print("wait for action to be done...")
    await event.wait()  # 等待事件被触发,不需要自己写轮询循环

async def function_B(event):
    await wait_for(event)
    print("performing next action...")

async def main():
    action_event = asyncio.Event()  # 创建事件对象
    await asyncio.gather(function_A(2, action_event), function_B(action_event))

asyncio.run(main())

这个方案里,event.wait()会自动挂起协程,直到event.set()被调用,不需要每隔0.1秒轮询一次,效率更高,代码也更简洁。

总结一下:你的问题核心是不可变类型的参数传递机制,用可变容器或者asyncio.Event都能解决,后者是异步场景下更地道的做法哦~

备注:内容来源于stack exchange,提问作者Frankie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 12:28:06