Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python While循环和异步_Python_Websocket_Python Asyncio - Fatal编程技术网

Python While循环和异步

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=

你好

我正在尝试编写一个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=['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
(whit
asyncio.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()解决了它