I am trying to work with a simple async example in Python, largely following this excellent answer here.
My goal is to set up a context variable and keep track of the series of calls by continuously appending to it. I know that context variables can be accessed with the .get()
method and their values altered with the .set()
method. In the below case however, the variable doesn't get modified despite the series of calls to the function sum()
that is apparent from the console.
Edit:
Based on Michael Butscher's comment below I replaced the original context variable (which was a string) with a list: output_list
and modified the list iteratively using .append()
. This now does enable me to view the final output but not the intermediate ones in the individual sum()
methods.
Full code:
import asyncio
import contextvars
import time
output_list = contextvars.ContextVar('output_list', default=list())
async def sleep():
print(f'Time: {time.time() - start:.2f}')
await asyncio.sleep(1)
async def sum(name, numbers):
total = 0
for number in numbers:
print(f'Task {name}: Computing {total}+{number}')
await sleep()
total += number
output_list.set(output_list.get().append(f"{name}"))
print(f'Task {name}: Sum = {total}\n')
print(f'Partial output from task {name}:', output_list.get())
start = time.time()
loop = asyncio.get_event_loop()
tasks = [
loop.create_task(sum("A", [1, 2])),
loop.create_task(sum("B", [1, 2, 3])),
]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()
end = time.time()
print(f'Time: {end-start:.2f} sec')
print("Final output_str =", output_list.get())
How can I iteratively follow the expansion of the context variable list output_list
?
My desired console output is:
Task A: Computing 0+1
Time: 0.00
Task B: Computing 0+1
Time: 0.00
Task A: Computing 1+2
Time: 1.02
Task B: Computing 1+2
Time: 1.02
Task A: Sum = 3
Partial output from task A: ['A']
Task B: Computing 3+3
Time: 2.02
Task B: Sum = 6
Partial output from task B: ['A', 'B']
Time: 3.03 sec
Final output_str = ['A', 'B']
Instead, I am getting:
Task A: Computing 0+1
Time: 0.00
Task B: Computing 0+1
Time: 0.00
Task A: Computing 1+2
Time: 1.02
Task B: Computing 1+2
Time: 1.02
Task A: Sum = 3
Partial output from task A: None
Task B: Computing 3+3
Time: 2.02
Task B: Sum = 6
Partial output from task B: None
Time: 3.03 sec
Final output_str = ['A', 'B']