使用 python socketserver 如何将变量传递给处理程序类的构造函数
我想将数据库连接传递给 EchoHandler 类,但是我根本不知道如何执行此操作或访问 EchoHandler 类。
class EchoHandler(SocketServer.StreamRequestHandler): def handle(self): print self.client_address, 'connected' if __name__ == '__main__': conn = MySQLdb.connect (host = "10.0.0.5", user = "user", passwd = "pass", db = "database") SocketServer.ForkingTCPServer.allow_reuse_address = 1 server = SocketServer.ForkingTCPServer(('10.0.0.6', 4242), EchoHandler) print "Server listening on localhost:4242..." try: server.allow_reuse_address server.serve_forever() except KeyboardInterrupt: print "\nbailing..."
I would like to pass my database connection to the EchoHandler class, however I can't figure out how to do that or access the EchoHandler class at all.
class EchoHandler(SocketServer.StreamRequestHandler): def handle(self): print self.client_address, 'connected' if __name__ == '__main__': conn = MySQLdb.connect (host = "10.0.0.5", user = "user", passwd = "pass", db = "database") SocketServer.ForkingTCPServer.allow_reuse_address = 1 server = SocketServer.ForkingTCPServer(('10.0.0.6', 4242), EchoHandler) print "Server listening on localhost:4242..." try: server.allow_reuse_address server.serve_forever() except KeyboardInterrupt: print "\nbailing..."
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
不幸的是,确实没有一种简单的方法可以直接从服务器外部访问处理程序。
您有两种选择来获取 EchoHandler 实例的信息:
server_forever()
之前添加server.conn = conn
)以及然后通过 self.server.conn 访问 EchoHandler.handler 中的该属性。我的最佳选择是:
Unfortunately, there really isn't an easy way to access the handlers directly from outside the server.
You have two options to get the information to the EchoHandler instances:
server.conn = conn
before callingserver_forever()
) and then access that property in EchoHandler.handler throughself.server.conn
.finish_request
and assign the value there (you would have to pass it to the constructor of EchoHandler and overwrite EchoHandler.__init__). That is a far messier solution and it pretty much requires you to store the connection on the server anyway.My optionon of your best bet:
Mark T 在 python list archive 上有如下说法
在 handler 类中, self.server 指的是服务器对象,所以 subclass
服务器并覆盖 init 以获取任何其他服务器参数
并将它们存储为实例变量。
Mark T has the following to say on the python list archive
In the handler class, self.server refers to the server object, so subclass
the server and override init to take any additional server parameters
and store them as instance variables.
我认为更Pythonic的另一种方法是执行以下操作:
您现在可以将处理程序的实例提供给TCPServer:
TCPServer通常会创建EchoHandler的新实例> 每个请求,但在这种情况下,将调用 __call__ 方法而不是构造函数(它已经是一个实例。)
在 call 方法中,我显式创建了一个副本当前 EchoHandler 并将其传递给超级构造函数符合“每个请求一个处理程序实例”的原始逻辑。
值得查看 SocketServer 模块以了解此处发生的情况: https://github.com/python/cpython/blob/2.7/Lib/SocketServer.py
Another way, that I believe more pythonic, is to do the following:
You can now give an instance of your handler to the TCPServer:
The TCPServer normally creates a new instance of EchoHandler per request but in this case, the __call__ method will be called instead of the constructor (it is already an instance.)
In the call method, I explicitly make a copy of the current EchoHandler and pass it to the super constructor to conform to the original logic of "one handler instance per request".
It is worth having a look at the SocketServer module to understand what happens here: https://github.com/python/cpython/blob/2.7/Lib/SocketServer.py
我目前正在解决同样的问题,但我使用了略有不同的解决方案,我觉得它稍微好一点,更通用(受到@aramaki的启发)。
在
EchoHandler
中,您只需覆盖__init__
并指定自定义Creator
方法。然后您可以调用
Creator
方法并传递您需要的任何内容。主要好处是,通过这种方式,您不会创建不必要的实例,并且可以以更易于管理的方式扩展类 - 您不需要再次更改
Creator
方法。I was currently solving same problem, but I used slightly different solution, I feel it's slightly nicer and more general (inspired by @aramaki).
In the
EchoHandler
you just need to overwrite__init__
and specify customCreator
method.Then you can just call the
Creator
method and pass anything you need.Main benefit is, that this way you are not creating any more instances than necessary and you are extending the class in more manageable way - you don't need to change the
Creator
method ever again.似乎您无法使用
ForkingServer
来共享变量,因为当进程尝试修改共享变量时会发生写入时复制。将其更改为 ThreadingServer,您将能够共享全局变量。
It seems that you can't use
ForkingServer
to share variables because Copy-on-Write happens when a process tries to modify a shared variable.Change it to
ThreadingServer
and you'll be able to share global variables.