Как обновить глобальную переменную в asyncio create_task - PullRequest
0 голосов
/ 22 марта 2020

В настоящее время у меня есть глобальная переменная, которая не устанавливается в приложении. У меня есть два файла, где file2 импортирует из file1. Глобал инициализируется в file1.

Вот код, который инициализирует глобальную переменную, а затем использует ее в файле 1.

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")

Вот код веб-сокета, который устанавливает для глобального значения значение true. Это находится в файле 2.

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()

Вот как этот код вызывается в файле2

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())

Порядок событий:

  • CONNECTION_OPEN is установлено значение false
  • Печатается «Установка соединения открыта в true»
  • Печатается «Соединение открыто»
  • «Значение все еще ложно» многократно печатается

Мне бы хотелось, чтобы значение глобальной переменной было обновлено так, чтобы выводилось «Это значение теперь истинно».

Ответы [ 2 ]

2 голосов
/ 22 марта 2020

Эта строка не делает то, что вы думаете:

from lights import calculate_idle,CONNECTION_OPEN 

Она не сделает CONNECTION_OPEN псевдонимом для lights.CONNECTION_OPEN; он создаст новую глобальную переменную (локальную для file2), инициализированную с текущим значением lights.CONNECTION_OPEN.

Правильный способ совместного использования глобальной modules это просто import lights (что в любом случае может быть хорошей идеей) и использование lights.CONNECTION_OPEN.

Лучшим вариантом является вообще не использовать глобальную переменную, а создать изменяемый объект, содержащий разделяемое состояние, и передать его коду, который должен поделиться им. Вы также можете добавить состояние к существующему объекту, необходимому для других целей, например, asyncio.Event, как предлагает @ gold_cy.

1 голос
/ 22 марта 2020

Просто используйте объект asyncio.Event в качестве глобальной переменной.

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())
...