Python:setup()vs __init __()用于socketserver的处理程序类

时间:2016-01-08 18:56:57

标签: python sockets socketserver

我正在尝试为socketserver定义一个处理程序类。当处理程序类没有定义__init__()方法时,我的服务器工作。客户端发送的消息被写入输出窗口。但是,当我添加一个__init__()方法来声明一个类成员时,我的程序引发了一个异常,因为RequestHandlerClass只需要一个参数,而我正在向它传递四个参数。在我的头撞到砖墙一段时间之后,我记得BaseRequestHandler类有一个可覆盖的setup()方法。我声明了它的覆盖并在其中声明了我的类成员,并且它起作用了。

虽然我能解决我当前的问题,但我想了解这一点。我是否应该在请求处理程序类中声明自己的__init__()方法?或者,如果我应该,它应该如何宣布?

这是我的代码:

import socketserver
import logging
import logging.config
import json
from TWMSMessageHandler import TWMSMessageHandler

class SingleTCPHandler(socketserver.BaseRequestHandler):
    # def __init__(self):   ## causes an error 
    def setup(self):
        self.messageHandler = TWMSMessageHandler()

    # One instance per connection.  Override handle(self) to customize action.
    def handle(self):
        # self.request is the client connection
        data = self.request.recv(1024)  # clip input at 1Kb

        dataString = data.decode()
        print ("Received data: " + dataString)
        self.request.close()

class MyTCPServer(socketserver.TCPServer):

    def __init__(self, serverAddress, handler):
        super().__init__(serverAddress, handler)

    def handle_timeout(self):
        print ("No message received in {0} seconds".format(self.timeout))

if __name__ == "__main__":
    with open('TWMSHandler_log_config.json', 'rt') as f:
        config = json.load(f)
    logging.config.dictConfig(config)

    tcpServer = MyTCPServer(("127.0.0.1", 5006), SingleTCPHandler)
    tcpServer.timeout = 30

    loopCount = 0
    while loopCount < 5:
        try:
            print ("About to wait for request")
            tcpServer.handle_request()
            print ("Back from handle_request")
            loopCount = loopCount + 1
        except Exception as Value:
            print ("Oops!  " + str(Value))
            break

1 个答案:

答案 0 :(得分:0)

我假设python 2.7,因为你还没有另外指定,但是这也应该适用于python 3.x.

如果你看一下源代码(https://hg.python.org/cpython/file/2.7/Lib/SocketServer.py#l631),你覆盖的BaseRequestHandler类除了self之外还需要3个参数:request, client_address, server。如果要覆盖__init__,则必须与此签名兼容,除非您还覆盖从TCPServer继承链中调用__init__的呼叫站点(您不想这样做)。

由于所有这些功能都是为了保存状态,否则你必须自己保存(或者通过super调用来调用基本功能),你也可以只使用setup