1

我对如何在 python 中使用 SocketServer.TCPServer 将变量发送到 TCPHandler 感到困惑。

HOST, PORT = hosts[0], args.port
server = SocketServer.TCPServer((HOST, PORT), METCPHandler)
server.serve_forever()

哪个电话:

class METCPHandler(SocketServer.BaseRequestHandler):           
    def handle(self):
        self.data = self.request.recv(1024).strip()
        print "{} wrote:".format(self.client_address[0])
        r = MExpressHandler(self.data, False)

但我想将调试布尔值传递给 MExpressHandler.. 所以

HOST, PORT = hosts[0], args.port
server = SocketServer.TCPServer((HOST, PORT), METCPHandler(debug))
server.serve_forever()

失败。这样做的正确方法是什么?我是否必须重新创建整个 TCPHandler 覆盖__init__

4

2 回答 2

3

相信你的直觉,正确的方法确实是继承 TCPServer 并覆盖该__init__方法,但是 Python 使这非常容易!

import SocketServer

class DebugTCPServer(SocketServer.TCPServer):
    def __init__(self, server_address, RequestHandlerClass, bind_and_activate=True, debug=True):
        self.debug = debug
        SocketServer.TCPServer.__init__(self, server_address, RequestHandlerClass, bind_and_activate=True)

class DebugMETCPHandler(SocketServer.BaseRequestHandler):
    def handle(self):
        # self.server is an instance of the DebugTCPServer
        DEBUG = self.server.debug
        self.data = self.request.recv(1024).strip()
        if DEBUG:
            print "{} wrote:".format(self.client_address[0])
        r = MExpressHandler(self.data, False)


server = DebugTCPServer((HOST, PORT), DebugMETCPHandler, debug=True)

或者因为我们指定debug=True为默认值:

server = DebugTCPServer((HOST, PORT), DebugMETCPHandler)
于 2013-04-08T21:51:23.497 回答
0

正如我在这篇文章中已经提出的那样,可以在不对 TCPServer 进行子类化的情况下做到这一点。它实际上更简洁和通用。

您可以通过以下方式为处理程序提供参数:

class METCPHandler(SocketServer.BaseRequestHandler):
  def __init__(self, debug):
    self.debug = debug

  def __call__(self, request, client_address, server):
    h = METCPHandler(self.debug)
    SocketServer.StreamRequestHandler.__init__(h, request, client_address, server)

您现在可以将处理程序的实例提供给 TCPServer:

SocketServer.TCPServer((HOST, PORT), METCPHandler(True))

TCPServer 通常会为每个请求创建一个新的METCPHandler实例,但在这种情况下,将调用 __call__方法而不是构造函数(它已经是一个实例。)

调用方法中,我显式地复制了当前的 METCPHandler 并传递给超级构造函数,以符合“一个请求一个处理程序实例”的原始逻辑。

值得看看 SocketServer 模块来了解这里发生了什么:https ://github.com/python/cpython/blob/2.7/Lib/SocketServer.py

于 2017-07-21T09:39:17.807 回答