Я пытаюсь получить из функции внутри асинхронной функции.Потратив часы на то, чтобы выяснить это и обойти переполнение стека, чтобы найти похожие вопросы, на которые уже были даны ответы, но не смог помочь мне найти решение своей проблемы, я попал сюда.
Проще говоря, я хочу запроситьИнтерфейс управления Asterisk через Panoramisk, используя веб-браузер и веб-сокеты.Когда пользователь подключается к серверу websocket, он запускает метод ws_handle
async def ws_handle(websocket, path):
await register(websocket)
try:
async for message in websocket:
data = json.loads(message)
...
. Затем я хочу получить некоторые данные, а затем доставить их клиенту.Проблема, с которой я сталкиваюсь, заключается в том, что я не могу просто сказать
exts = yield from ExtensionStateList.get(AmiManager)
, где функция ExtensionStateList.get (примерно), как показано ниже:
def get(AmiManager):
queues_details = yield from AmiManager.send_action(
{'Action': 'ExtensionStateList'})
...
val = {
'extensions': EXTENSIONS,
'parks': PARKS,
'paging': PAGING,
'confrences': CONFRENCES,
'apps': APPS,
'misc': MISC
}
return val
У меня естьиспользовал этот же файл ExtensionStateList.py в другом тестовом файле, отдельном от моего файла сервера websockets, в неасинхронном методе, вызывая его, как показано выше,
exts = yield from ExtensionStateList.get(AmiManager)
без проблем, и он заполняет exts с помощьюзначение, возвращаемое функцией.
Мои исследования заставляют меня перебирать его так:
async for a in ExtensionStateList.get(AmiManager):
yield a
, но я не знаю, как использовать его для заполнения переменной, которую я хочу заполнить,Я пытался так:
exts = ''
async for a in ExtensionStatList.get(AmiManager):
exts = exts+a
только чтобы сказать, что он не может присоединить AsyncIO.Future к строке.Я также попытался поменять return val
на yield val
, опять же без удачи.
Очевидно, для меня это недостаток в моих недостатках знания Python.Что я могу сделать?Я думал, что, возможно, я мог бы изменить ExtensionStateList.get на асинхронный, но это отбросило бы меня обратно в ту же лодку, в которой я сейчас нахожусь?
ДОПОЛНИТЕЛЬНО
У меня естьпродолжил поиск в StackOverflow и нашел следующий вопрос:
В чем разница между декораторами @ types.coroutine и @ asyncio.coroutine?
Мне кажется, чтовозможно, если я добавлю @asyncio.coroutine
в строке выше ws_handle
, например, так:
@asyncio.coroutine
async def ws_handle(websocket, path):
, что я тогда смогу:
exts = yield from ExtensionStateList.get(AmiManager)
Однако я нахожу, что этоне работает, и это говорит мне, что я не могу дать изнутри асинхронной функции.Я неправильно понимаю, что я читаю здесь?Или я, может быть, не правильно его реализую?Я на правильном пути с этим?
Согласно ответу, приведенному здесь:
'yield from' внутри асинхронной функции Python 3.6.5 aiohttp
Я также пытался дождаться функции следующим образом:
exts = await ExtensionStateList.get(AmiManager)
Однако Python сообщает мне, что генератор объектов нельзя использовать в выражении ожидания.
FURTHERMORE
Для тех, кого это может заинтересовать, так я вызываю свою функцию ws_handle.Он вызывается при создании сервера веб-сокетов, и сервер веб-сокетов отвечает за отправку / вызов? функции ws_handle.
Мне кажется, что он вызывает эту функцию один раз для каждого клиентакто подключается, и эта функция работает до тех пор, пока пользователь не отключится.
WebsocketServer = websockets.serve(ws_handle, host, port)
asyncio.get_event_loop().run_until_complete(WebsocketServer)
asyncio.get_event_loop().run_forever()
ADDENDUM
Да, снова я добавляю еще больше.Я изменил свой ExtensionStateList.py, чтобы при вызове метода get он выполнялся следующим образом:
async def get(AmiManager):
val = await getInternal(AmiManager)
return val
@asyncio.coroutine
def getInternal(AmiManager):
Теперь я могу использовать yield from
внутри функции getInternal, которая ранее была моей функцией getи я могу позвонить и получить дату, как показано ниже:
exts = await ExtensionStateList.get(AmiManager)
Мне кажется, я это понимаю, и я вижу, как это два разных способа сделать почти одно и то же.
Спасибо, что указали мне правильное направление, ребята!