¿Cómo puedo manejar las variables de contexto en asyncio mientras se encuentran en un ciclo ‘while’?
El contexto de la variable ‘value’ no cambia a medida que pasa por el ciclo ‘while’.
”’
import contextvars
import keyboard
import asyncio
import random
value = contextvars.ContextVar('value')
value.set('-')
async def q():
while True:
await asyncio.sleep(1)
print(value.get())
async def s():
while True:
x = random.choice(list(range(10)))
value.set(x)
await asyncio.sleep(1)
async def main():
t1 = asyncio.create_task(q())
t2 = asyncio.create_task(s())
await t1
asyncio.run(main())
La salida es ”—”. Quiero establecer un nuevo valor para esta variable de contexto, pero no puedo encontrar casos similares.
Es mi primera vez aquí, así que no sé si se muestran correctamente todas las imágenes y no sé cómo pegar un código aquí, así que por favor ayuda
davy.ai
El problema parece estar relacionado con el hecho de que la variable de contexto
value
se establece dentro del buclewhile True
de la corutinas()
, pero no se accede a ella dentro del mismo bucle. En cambio, se accede dentro del buclewhile True
de la corutinaq()
. Esto significa que el valor devalue
no cambiará hasta que la corutinas()
ceda el control al bucle de eventos, lo cual ocurre cada vez que esperaasyncio.sleep(1)
.Para demostrar esto, puedes modificar la corutina
s()
para que imprima el valor devalue
cada vez que lo establece:Si ejecutas el código modificado, verás que la variable de contexto
value
se establece en un nuevo valor cada vez que se ejecuta la corutinas()
, pero la salida de la corutinaq()
solo muestra el último valor establecido antes de que el bucle de eventos ceda el control:Para solucionar esto, podrías modificar la corutina
q()
para ceder el control al bucle de eventos cada vez que imprima el valor devalue
, agregando una instrucciónawait asyncio.sleep(0)
antes de cada instrucciónprint
:Con esta modificación, la salida de la corutina
q()
mostrará el valor actualizado devalue
cada vez que la corutinas()
lo establezca:Ten en cuenta que
asyncio.sleep(0)
se utiliza para ceder el control al bucle de eventos sin bloquear la corutina, lo que permite que se ejecuten otras corutinas en el ínterin. Sin ello, la corutinaq()
nunca cedería el control al bucle de eventos y la corutinas()
nunca tendría la oportunidad de establecer el valor devalue
.