Python While循环和异步
你好 我正在尝试编写一个WebSocket连接器并使用asyncio。我不太熟悉异步方法,因此会出现错误行为。下面是代码的简化版本Python While循环和异步,python,websocket,python-asyncio,Python,Websocket,Python Asyncio,你好 我正在尝试编写一个WebSocket连接器并使用asyncio。我不太熟悉异步方法,因此会出现错误行为。下面是代码的简化版本 import pandas as pd import json import websockets import asyncio import time class BinanceQuotesWS: def __init__(self,client,pair): self.quotes = pd.DataFrame(columns=
import pandas as pd
import json
import websockets
import asyncio
import time
class BinanceQuotesWS:
def __init__(self,client,pair):
self.quotes = pd.DataFrame(columns=['Timestamp','Price'])
self.pair = pair
self.socket='wss://fstream.binance.com/ws'
self.websocket = None
self.loop = None
self.result = None
def get_quotes(self):
return self.quotes
def start(self):
self.loop = asyncio.get_event_loop()
self.result = self.loop.create_task(self.connect())
async def connect(self):
self.websocket = await websockets.connect(self.socket)
await self.subscribe_quotes()
async def subscribe_quotes(self):
subscribe_message = {
"method": "SUBSCRIBE",
"params":
[
self.pair.lower()+"@trade"
],
"id": 1
}
subscribe_message = json.dumps(subscribe_message)
await self.websocket.send(subscribe_message)
async for msg in self.websocket:
msg = json.loads(msg)
if('p' in msg):
self.quotes.loc[0] = [msg['E'],float(msg['p'])]
temp_ws = BinanceQuotesWS(client,'BTCUSDT')
temp_ws.start()
当我在Jupyter中测试它并手动执行带有temp\u ws.get\u quotes()
的单元格时,每次都会返回带有新引号的正确数据帧
虽然在我的程序中,我需要一些无限循环,但出现了一个错误
while(True):
quotes = temp_ws.get_quotes()
print(quotes)
time.sleep(3)
quotes
DF始终为空,但我无法找出原因(可能是因为while循环阻塞)。如果有人能帮我解决这个问题,我会很高兴的(如果代码中还有其他东西可以在异步请求方面改进的话,我会给出一些提示)。谢谢。您可以使用asyncio.sleep
创建async
函数
async def display(self):
while True:
await asyncio.sleep(3)
quotes = self.get_quotes()
print('time:', quotes['Timestamp'][0], 'price:', quotes['Price'][0])
并将其添加到循环中
self.result2 = self.loop.create_task(self.display())
然后你可以在同一个循环中运行所有的程序
temp_ws.loop.run_forever()
如果您不使用run\u forever()
,则它不会运行connect()
——并且您不会在标准循环中获取值。但是这个循环必须一直运行,不能与普通循环同时运行(普通循环也必须一直运行)。其中一个循环必须在单独的线程中运行
但wait
(whitasyncio.sleep
)解决了这个问题。当它在中休眠而为True时
则转到其他函数并可以运行其他代码-稍后,其他一些代码使用等待
,然后返回到而为True时
也许在
Jupyter
中,它可以与run\u forever()
一起工作,因为它们添加了许多额外的函数,使生活更简单(而Jupyter
中使用的元素可能需要此循环才能正确工作),但在正常程序中,您必须手动使用run\u forever()
最低工作代码:
import pandas as pd
import json
import websockets
import asyncio
import time
class BinanceQuotesWS:
def __init__(self,client,pair):
self.quotes = pd.DataFrame(columns=['Timestamp','Price'])
self.pair = pair
self.socket='wss://fstream.binance.com/ws'
self.websocket = None
self.loop = None
self.result = None
def get_quotes(self):
return self.quotes
def start(self):
self.loop = asyncio.get_event_loop()
self.result = self.loop.create_task(self.connect())
self.result2 = self.loop.create_task(self.display())
async def connect(self):
self.websocket = await websockets.connect(self.socket)
await self.subscribe_quotes()
async def subscribe_quotes(self):
subscribe_message = {
"method": "SUBSCRIBE",
"params": [
self.pair.lower()+"@trade"
],
"id": 1
}
subscribe_message = json.dumps(subscribe_message)
await self.websocket.send(subscribe_message)
async for msg in self.websocket:
msg = json.loads(msg)
if('p' in msg):
self.quotes.loc[0] = [msg['E'],float(msg['p'])]
#print(self.quotes)
async def display(self):
while True:
await asyncio.sleep(3)
quotes = self.get_quotes()
print('time:', quotes['Timestamp'][0], 'price:', quotes['Price'][0])
client = ''
temp_ws = BinanceQuotesWS(client,'BTCUSDT')
temp_ws.start()
temp_ws.loop.run_forever()
如果您使用异步,那么您应该在异步循环中运行它,而不是在自己的正常循环中。您应该为此使用
async.sleep
。或者您必须在单独的线程中运行其中一个循环。谢谢。出于某种原因,出现了一个错误RuntimeError:这个事件循环已经在python中运行了
,但我用import nest\u asyncio nest\u asyncio.apply()解决了它