Я пытаюсь написать фрагмент, чтобы изучить Python asyncio. Основная идея заключается в том:использовать asyncio обновлять некоторые данные своевременно и присутствовать через aiohttp?
использование «простой» веб-сервер (aiohttp) представить некоторые данные пользователя
возвращаемые данные для пользователя будет меняться оперативно
здесь код:
import asyncio
import random
from aiohttp import web
userfeed = [] # the data suppose to return to the user via web browsers
async def data_updater(): #to simulate data change promptly
while True:
await asyncio.sleep(3)
userfeed = [x for x in range(random.randint(1, 20))]
print('user date updated: ', userfeed)
async def web_handle(request):
text = str(userfeed)
#print('in handler:', text) # why text is empty?
return web.Response(text=text)
async def init(loop):
app = web.Application(loop=loop)
app.router.add_route('GET', '/', web_handle)
srv = await loop.create_server(app.make_handler(), '127.0.0.1', 8000)
print('Server started @ http://127.0.0.1:8000...')
return srv
loop = asyncio.get_event_loop()
asyncio.ensure_future(data_updater())
asyncio.ensure_future(init(loop))
loop.run_forever()
проблема, код работает (питон 3,5), но userfeed
всегда пусто в браузерах, а также в web_handler()
:-(
- почему
userfeed
не был обновлен? - относительно этого
timely date update
функция, потому что механизм обновления может быть более сложным позже сказать, что асинхронный запрос ожидания может быть задействован, есть ли лучший способ вместо того, чтобы использоватьwhile True: await asyncio.sleep(3)
вdata_updater()
, чтобы получить «более точный» таймер?
Вы хотите получать уведомления пользователю, просматривающему вашу страницу (без каких-либо действий от него)? Если это так, вы должны взглянуть на технологию * websocket *, она реализована в 'aiohttp' довольно простым способом (есть [примеры] (https://github.com/KeepSafe/aiohttp/blob/master/ примеры/web_ws.py) в исходном коде). В противном случае вы должны использовать свой объект '' app' (http://aiohttp.readthedocs.io/en/stable/faq.html#id3) (который предоставляет интерфейс 'dict') для передачи переменной' userfeed' между функциями и избегать его глобального. – mgc
@ mgc, спасибо, что ответили. Я не хочу, чтобы данные автоматически очищались в браузере пользователя, просто модель клиентского тяги могла бы быть достаточной - каждый раз, когда вы открываете URL-адрес через браузер или инструмент вроде wget, могут появляться последние данные. Путаница здесь в том, почему глобальная переменная не обновлялась (внутри 'web_handler()' print показывает, что она всегда [], но 'data_updater()' печатать изменено)? async def отличается от обычного def, он каким-то образом кэширует контекст? – user340307
См. Мой ответ для примера, так как использование глобальной переменной в этом контексте явно обескураживается [документацией] (http://aiohttp.readthedocs.io/en/stable/web.html#data-sharing-aka-no- одиночки-пожалуйста). Но если вам действительно нужно заставить его работать с помощью глобального 'userfeed', просто добавьте' global userfeed' в функции 'data_updated' и' web_handle', и он должен работать (таким образом функция знает, что 'userfeed' относится к переменной расположенный в глобальном масштабе, в вашем примере каждая функция имела свой собственный локальный 'userfeed'). – mgc