Skip to main content
 首页 » 编程设计

python之在 python TCP 服务器中向 handle() 添加功能的正确方法

2025年05月04日12powertoolsteam

我有这样的代码:

class SingleTCPHandler(SocketServer.BaseRequestHandler): 
    """ One instance per connection. """ 
    def handle(self): 
        data = Net.recv_from_socket(self.request) 
        GUI.run(str("RECV'd message: %s" % data)) 
 
class SimpleServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer): 
    def __init__(self, server_address, RequestHandlerClass): 
        SocketServer.TCPServer.__init__(self, server_address, RequestHandlerClass) 

但我不想使用全局变量 GUI 来包含我在服务器收到消息时要调用的函数。相反,我想向 SingleTCPHandler 类发送 GUI 对象,这样它就可以在本地调用函数,而不是引用全局变量。

想法?对 python 有点陌生...

请您参考如下方法:

将您的处理程序更改为

class SingleTCPHandler(SocketServer.BaseRequestHandler): 
    """ One instance per connection. """ 
    def __init__(self, callback, *args, **keys): 
        self.callback = callback 
        SocketServer.BaseRequestHandler.__init__(self, *args, **keys) 
 
    def handle(self): 
        data = Net.recv_from_socket(self.request) 
        self.callback(data) 

稍后(您创建 TCP 服务器的地方):

def show_message_box(data): 
    GUI.run(str("RECV'd message: %s" % data)) 
def handler_factory(callback): 
    def createHandler(*args, **keys): 
        return ThreadedTCPRequestHandler(callback, *args, **keys) 
    return createHandler 
server = ThreadedTCPServer((HOST, PORT), handler_factory(show_message_box)) 

解释:

1) handler_factory 被调用了应该被调用的回调。

2) handler_factory 创建了一个名为 createHandler 的新函数。这个功能会交给ThreadedTCPServer。它会在需要创建新处理程序时调用它。

3) 调用时,它会创建您的 ThreadedTCPRequestHandler 并将回调参数(在本例中为 show_message_box)移交给存储它的 ThreadedTCPRequestHandler.init。这背后的“魔法”被称为“闭包”。 IE。您可以从内部函数 createHandler 中的外部函数 handler_factory 访问回调参数。 Google 搜索“closure python”,您会得到一些很好的解释。

4) 当最终调用 handle() 时,它调用 self.callback(data)。由于 self.callback 是 show_message_box,show_message_box(data) 将被有效调用。

还有一些更简短的表达方式:

def my_callback(): 
    print 'Hello' 
server = ThreadedTCPServer((HOST, PORT), lambda *args, **keys: ThreadedTCPRequestHandler(my_callback, *args, **keys)) 

会工作,就像

def my_callback(): 
    print 'Hello' 
import functools 
server = ThreadedTCPServer((HOST, PORT), functools.partial(ThreadedTCPRequestHandler, my_callback)) 

我不知道你的具体用例,但如果你需要用套接字做更多的事情,你可能想看看 http://www.twistedmatrix.com (流行的 python 网络包)。您还应该意识到很多 GUI 系统不喜欢从多个线程同时运行,因此您需要注意这一点。