首页 > 解决方案 > 如何阻止我的函数每次运行前 3 行?

问题描述

我正在尝试制作和绘制一些图表并比较一些价格数据,这比手动操作更有效。下面我包含了到目前为止我编写的代码,这花了我两周的时间。

我已经成功到达 Kraken websocket,并且能够从返回的 json 中收集我需要的数据。

我希望这一切都适合一个简洁的功能,所以到时候我可以轻松地将其中的一堆一起使用。

由于底部while True语句,每次打印价格数据时都会重复第 4 行和第 5 行...

当这段代码不是一个函数时,它的行为完全符合预期,并在更改时返回/打印出价和要价。

def kraken_price():
    import websocket
    import json
    wskraken = websocket.create_connection("wss://ws.kraken.com/")
    wskraken.send('{"event":"subscribe", "subscription":{"name":"ticker"}, "pair":["XBT/USD"]}')
    while True:

        # websockets received data cast to a variable
        received = wskraken.recv()
        # if the received data is only a heartbeat it must be ignored

        if received == '{"event":"heartbeat"}':
            pass

        else:
            # takes the string received from the websocket and converts it to a json object
            jdata_loads = json.loads(received)

            try:
                krakenAsk = jdata_loads[1]["a"][0]
                krakenBid = jdata_loads[1]["b"][0]
                return krakenAsk, krakenBid

            except:
                print('connection to Kraken websockets is being established')

while True:
    print(kraken_price())

标签: pythonfunctionwebsocket

解决方案


我建议将您的功能变成生成器。这将允许调用者和函数之间更清晰的交互:

import websocket
import json

def kraken_price():
    wskraken = websocket.create_connection("wss://ws.kraken.com/")
    wskraken.send('{"event":"subscribe", "subscription":{"name":"ticker"}, "pair":["XBT/USD"]}')
    while True:

        # websockets received data cast to a variable
        received = wskraken.recv()
        # if the received data is only a heartbeat it must be ignored

        if received == '{"event":"heartbeat"}':
            pass

        else:
            # takes the string received from the websocket and converts it to a json object
            jdata_loads = json.loads(received)

            krakenAsk = jdata_loads[1]["a"][0]
            krakenBid = jdata_loads[1]["b"][0]
            yield krakenAsk, krakenBid

for ask, bid in kraken_price():
    print(ask, bid)

导入通常位于脚本的顶部。

当您yield在函数中的任何位置使用时,它就会成为生成器函数。它现在返回一个可迭代的对象,该对象与您的外for循环同步生成所需的值。

您可能希望在第一个生成器函数的行之后用一个try: ... finally: ...块包围以关闭连接,无论它如何工作。此时,您可能希望在连接上使用上下文管理。


推荐阅读