使用websocket客户端作为python中的类

jbs*_*ssm 7 python class websocket

我正在尝试使用websockets访问一些数据,但我无法真正解决websockets文档中给出的示例.

我有这个代码,并希望在类中转换它

import websocket
import thread
import time

def on_message(ws, message):
    print message

def on_error(ws, error):
    print error

def on_close(ws):
    print "### closed ###"

def on_open(ws):
    def run(*args):
        for i in range(3):
            time.sleep(1)
            ws.send("Hello %d" % i)
        time.sleep(1)
        ws.close()
        print "thread terminating..."
    thread.start_new_thread(run, ())


if __name__ == "__main__":
    websocket.enableTrace(True)
    ws = websocket.WebSocketApp("ws://echo.websocket.org/",
                                on_message = on_message,
                                on_error = on_error,
                                on_close = on_close)
    ws.on_open = on_open

    ws.run_forever()
Run Code Online (Sandbox Code Playgroud)

我们的想法是在类中使用所有websocket功能,这样我就可以创建该类的对象.

我试着开始这样做,但我甚至无法通过这个:

class MySocket(object):
    def __init__(self):
        websocket.enableTrace(True)
        self.ws = websocket.WebSocketApp("ws://echo.websocket.org:12300/foo",
                                    on_message = on_message,
                                    on_error = on_error,
                                    on_close = on_close)

    def on_message(ws, message):
        print message

    def on_error(ws, error):
        print error

    def on_close(ws):
        print "### closed ###"

    def on_open(ws):
    ws.send("Hello %d" % i)
Run Code Online (Sandbox Code Playgroud)

该错误立即开始,on_message说这是一个"未解决的参考".

Eug*_*ene 10

将调用打包在一个匿名lambda函数中,以实现正确的调用self:

class Client:
    def __init__(self, db, symbols):
        self.ws = websocket.WebSocketApp("wss://the.server.com/api",
                    on_message = lambda ws,msg: self.on_message(ws, msg),
                    on_error   = lambda ws,msg: self.on_error(ws, msg),
                    on_close   = lambda ws:     self.on_close(ws),
                    on_open    = lambda ws:     self.on_open(ws))

    def on_message(self, ws, message):
            msg = json.loads(message)
            print(msg)
    ...
Run Code Online (Sandbox Code Playgroud)

  • 这似乎是解决问题的正确方法 (2认同)

aba*_*ert 5

WebSocketApp其回调的需求可调用的对象(包括您在构造函数中,像传递者on_message,和一个你在事后设置,on_open).

普通函数是可调用对象,因此您的非OO版本可以正常工作,因为您传递的是普通函数.

绑定方法也是可调用对象.但是你的OO版本没有传递绑定方法.顾名思义,绑定方法绑定到对象.您可以使用obj.method表示法执行此操作.在你的情况下,那是self.on_message:

self.ws = websocket.WebSocketApp("ws://echo.websocket.org/",
                                 on_message = self.on_message,
                                 on_error = self.on_error,
                                 on_close = self.on_close)
self.ws.on_open = self.on_open
Run Code Online (Sandbox Code Playgroud)

但是,你还有另外一个问题.虽然这会使您的错误消失,但它不会使您的代码真正起作用.一个常规方法必须self作为它的第一个参数:

def on_message(self, ws, message):
    print message
Run Code Online (Sandbox Code Playgroud)

同样值得注意的是,你并没有真正使用这个课程.如果你永远不会访问任何东西self,那么这个类就像一个命名空间.并不是说这总是一件坏事,但这通常表明你需要至少考虑一下你的设计.你需要保持任何状态吗?如果没有,为什么你想要一个班级?

您可能希望重读有关类教程部分以了解方法self等.


小智 2

您需要将“self”添加到类方法中:

class MySocket(object):
    def __init__(self):
        websocket.enableTrace(True)
        self.ws = websocket.WebSocketApp("ws://echo.websocket.org:12300/foo",
                                on_message = self.on_message,
                                on_error = self.on_error,
                                on_close = self.on_close)

    def on_message(self, ws, message):
        print message

    def on_error(self, ws, error):
        print error

    def on_close(self, ws):
        print "### closed ###"

    def on_open(self, ws):
        ws.send("Hello %d" % i)
Run Code Online (Sandbox Code Playgroud)