为什么缺少 __init__() 的参数?

Why is a parameter to __init__() missing?

总结

我有一个使用 Websockets 的客户端-服务器应用程序。后端(服务器)部分使用 autobahn.

在 Python 中实现

服务器除了为 Websockets 端点提供服务外,还运行一系列线程,通过 queue.Queue().

为 Websockets 通道提供数据。

其中一个线程有问题:它在缺少参数时崩溃并在解决异常时挂起。

实施细节

服务器实现(删减以突出问题):

from autobahn.asyncio.websocket import WebSocketServerProtocol, WebSocketServerFactory
import time
import threading
import arrow
import queue
import asyncio
import json

# backends of components
import dummy

class MyServerProtocol(WebSocketServerProtocol):
    def __init__(self):
        super().__init__()
        print("webserver initialized")
        # global queue to handle updates from modules
        self.events = queue.Queue()
        # consumer
        threading.Thread(target=self.push).start()
        threading.Thread(target=dummy.Dummy().dummy, args=(self.events,)).start()

    def push(self):
        """ consume the content of the queue and push it to the browser """
        while True:
            update = self.events.get()
            print(update)
            if update:
                self.sendMessage(json.dumps(update).encode('utf-8'), False)
                print(update)
            time.sleep(1)


    def worker(self):
        print("started thread")
        while True:
            try:
                self.sendMessage(arrow.now().isoformat().encode('utf-8'), False)
            except AttributeError:
                print("not connected?")
            time.sleep(3)

    def onConnect(self, request):
        print("Client connecting: {0}".format(request.peer))

    def onOpen(self):
        print("WebSocket connection open.")

    def onClose(self, wasClean, code, reason):
        print("WebSocket connection closed: {0}".format(reason))


if __name__ == '__main__':

    factory = WebSocketServerFactory(u"ws://127.0.0.1:9100")
    factory.protocol = MyServerProtocol

    loop = asyncio.get_event_loop()
    coro = loop.create_server(factory, '0.0.0.0', 9100)
    loop.run_until_complete(coro)
    loop.run_forever()

上面代码中导入的dummy模块:

import time
import arrow

class Dummy:
    def __init__(self, events):
        self.events = events
        print("dummy initialized")

    def dummy(self):
        while True:
            self.events.put({
                'dummy': {
                    'time': arrow.now().isoformat()
                }
            })
            time.sleep(1)

问题

当 运行 上面的代码并从客户端连接时,我得到输出 webserver initialized (证明连接已启动),并在客户端上得到 WebSocket connection to 'ws://127.0.0.1:9100/' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED

调试代码时,我看到对 threading.Thread(target=dummy.Dummy().dummy, args=(self.events,)).start() 的调用崩溃,调试器 (PyCharm) 将我引导至 C:\Program Files (x86)\Python36-32\Lib\asyncio\selector_events.py,特别是第 236 行

# It's now up to the protocol to handle the connection.
except Exception as exc:
    if self._debug:

线程在执行 if self._debug 时挂起,但我在 except 行(感谢 Pycharm)看到

exc: __init__() missing 1 required positional argument: 'events'

我的问题

为什么缺少这个参数?它通过 threading.Thread(target=dummy.Dummy().dummy, args=(self.events,)).start() 调用提供。

作为附带问题:为什么线程在 if 条件下挂起?

备注

构造函数需要 events arg,而不是 dummy 方法。我认为你的意思更像是:

d = Dummy(self.events)
threading.Thread(d.dummy).start()