使用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..." 类EchoHandler(SocketServer.StreamRequestHandler): def句柄(自身): 打印self.client_地址“已连接” 如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu': conn=MySQLdb.connect(host=“10.0.0.5”,user=“user”,passwd=“pass”,db=“database”) SocketServer.ForkingCpserver.allow_reuse_address=1 server=SocketServer.forkingcpserver(('10.0.0.6',4242),EchoHandler) 打印“本地主机上的服务器侦听:4242…” 尝试: server.allow\u重用\u地址 服务器。永远为您服务() 除键盘中断外: 打印“\n行李…”使用python socketserver,如何将变量传递给处理程序类的构造函数,python,python-2.7,socketserver,Python,Python 2.7,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
不幸的是,实际上没有一种简单的方法可以直接从服务器外部访问处理程序 您有两个选项来获取EchoHandler实例的信息:
server\u forever()
之前添加server.conn=conn
),然后通过self.server.conn
访问EchoHandler.handler中的该属性finish\u请求
并在那里分配值(您必须将其传递给EchoHandler的构造函数并覆盖EchoHandler.\uuuuu init\uuuuuu)。这是一个非常混乱的解决方案,它几乎要求您将连接存储在服务器上class EchoHandler(SocketServer.StreamRequestHandler):
def handle(self):
# I have no idea why you would print this but this is an example
print( self.server.conn );
print self.client_address, 'connected'
if __name__ == '__main__':
SocketServer.ForkingTCPServer.allow_reuse_address = 1
server = SocketServer.ForkingTCPServer(('10.0.0.6', 4242), EchoHandler)
server.conn = MySQLdb.connect (host = "10.0.0.5",
user = "user", passwd = "pass", db = "database")
# continue as normal
Mark T在python列表归档中有以下几点要说 在处理程序类中,self.server引用服务器对象,因此子类 服务器和重写init以获取任何其他服务器参数 并将它们存储为实例变量
import SocketServer
class MyServer(SocketServer.ThreadingTCPServer):
def __init__(self, server_address, RequestHandlerClass, arg1, arg2):
SocketServer.ThreadingTCPServer.__init__(self,
server_address,
RequestHandlerClass)
self.arg1 = arg1
self.arg2 = arg2
class MyHandler(SocketServer.StreamRequestHandler):
def handle(self):
print self.server.arg1
print self.server.arg2
另一种方法,我认为更像是python,是做以下事情:
class EchoHandler(SocketServer.StreamRequestHandler):
def __init__(self, a, b):
self.a = a
self.b = b
def __call__(self, request, client_address, server):
h = EchoHandler(self.a, self.b)
SocketServer.StreamRequestHandler.__init__(h, request, client_address, server)
现在,您可以将处理程序的实例提供给TCPServer:
SocketServer.ForkingTCPServer(('10.0.0.6', 4242), EchoHandler("aaa", "bbb"))
TCPServer通常会为每个请求创建一个新的EchoHandler实例,但在这种情况下,将调用\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu>方法,而不是
在调用方法中,我显式复制当前EchoHandler并将其传递给超级构造函数,以符合“每个请求一个处理程序实例”的原始逻辑
值得一看SocketServer模块,以了解这里发生了什么:我目前正在解决相同的问题,但我使用了稍微不同的解决方案,我觉得它稍微好一些,更通用一些(受@aramaki的启发) 在
EchoHandler
中,您只需覆盖\uuuu init\uuuu
并指定自定义创建者
方法
class EchoHandler(SocketServer.StreamRequestHandler):
def __init__(self, request, client_address, server, a, b):
self.a = a
self.b = b
# super().__init__() must be called at the end
# because it's immediately calling handle method
super().__init__(request, client_address, server)
@classmethod
def Creator(cls, *args, **kwargs):
def _HandlerCreator(request, client_address, server):
cls(request, client_address, server, *args, **kwargs)
return _HandlerCreator
然后,您可以调用Creator
方法并传递所需的任何内容
SocketServer.ForkingTCPServer(('10.0.0.6', 4242), EchoHandler.Creator(0, "foo"))
主要的好处是,通过这种方式,您不会创建任何超出需要的实例,并且您以更易于管理的方式扩展了类-您不需要再次更改
创建者
方法。为什么不super()。\uu init\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu(…)
而改为在MyServer中。\uuuuu init“老式”类。必须以这种方式调用超级构造函数。请参见此处:@ShivangiSingh可能最好发布一个问题。然后我们可以查看您的代码。