How to update global variable in asyncio create_task

给你一囗甜甜゛ 提交于 2020-03-25 18:22:41

问题


I currently have a global variable that's not being set across the application. I have two files where file2 imports from file1. The global is intialized in file1.

Here is the code that initializes the global variable and later uses it in file1.

import time
import asyncio

#Initialize global
CONNECTION_OPEN = False

async def calculate_idle(t):
    orig_time = t
    global CONNECTION_OPEN
    while True:
        await asyncio.sleep(5)
        print("GLOBAL CONNECTION", CONNECTION_OPEN)
        if CONNECTION_OPEN:
            print("This value is now true")
        else:
             print("Value is still false")

Here is the websocket code that is setting the global to true. This is located in file2.

import os
import asyncio
import websockets
import json
import threading
import time
from random import randrange
from enum import Enum
from lights import calculate_idle,CONNECTION_OPEN 

async def init_connection(message):
    #Get global variable to set
    global CONNECTION_OPEN
    global CLIENT_WS
    uri = WS_URI
    async with websockets.connect(uri) as websocket:
        print("Setting Connection open to true")
        CONNECTION_OPEN = True
        CLIENT_WS = websocket
        # send init message
        await websocket.send(message)
        print("Connection is open") 
        while CONNECTION_OPEN:
            await handleMessages(websocket, message)
        await websocket.send(json.dumps({'type': MessageType.Close.name, 'message': USERNAME}))
        await websocket.close()

Here is how this code is called in file2

async def main():
    message = json.dumps({'payload': 
                            'payload')
    loop = asyncio.get_event_loop()
    start_light = asyncio.create_task(calculate_idle(3))
    await asyncio.gather(init_connection(message), start_light)

asyncio.run(main())

The order of events is:

  • CONNECTION_OPEN is set to false
  • "Setting connectoin open to true" is printed
  • "Connection is open" is printed
  • "Value is still false" is repeatedly printed

I'd like the global variable value to be updated so that "This value is now true" is printed.


回答1:


This line doesn't do what you think it does:

from lights import calculate_idle,CONNECTION_OPEN 

It won't make CONNECTION_OPEN an alias for lights.CONNECTION_OPEN; it will create a new global variable (local to file2) initialized with the current value of lights.CONNECTION_OPEN.

The correct way to share a global among modules is to just import lights (which might be a good idea anyway) and use lights.CONNECTION_OPEN.

A better option is to not use a global variable at all, but to create a mutable object that contains the shared state, and pass it to the code that needs to share it. You can also add the state to an existing object needed for other things, such as an asyncio.Event, as suggested by @gold_cy.




回答2:


Just use an asyncio.Event object as the global variable.

import time
import asyncio


async def calculate_idle(t, conn_open_event):
    orig_time = t
    while True:
        await conn_open_event.wait()
        print("Connection is now open from idle")

import os
import asyncio
import websockets
import json
import threading
import time
from random import randrange
from enum import Enum
from lights import calculate_idle

async def init_connection(message, conn_open_event):
    #Get global variable to set
    global CLIENT_WS
    uri = WS_URI
    async with websockets.connect(uri) as websocket:
        print("Connection is open from socket")
        conn_open_event.set()
        CLIENT_WS = websocket
        CONNECTION_OPEN = True
        # send init message
        await websocket.send(message) 
        while CONNECTION_OPEN:
            await handleMessages(websocket, message)
        await websocket.send(json.dumps({'type': MessageType.Close.name, 'message': USERNAME}))
        await websocket.close()

async def main():
    message = json.dumps({'payload': 
                            'payload')
    loop = asyncio.get_event_loop()
    event = asyncio.Event()
    start_light = asyncio.create_task(calculate_idle(3, event))
    await asyncio.gather(init_connection(message, event), start_light)

asyncio.run(main())


来源:https://stackoverflow.com/questions/60801288/how-to-update-global-variable-in-asyncio-create-task

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!