2011-07-29 14 views
13

Me gustaría pasar la conexión de mi base de datos a la clase EchoHandler, sin embargo no puedo encontrar la manera de hacerlo o acceder a la clase EchoHandler en absoluto .Con python socketserver ¿cómo puedo pasar una variable al constructor de la clase de controlador

 

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..." 

Respuesta

23

Desafortunadamente, realmente no hay una manera fácil de acceder a los controladores directamente desde fuera del servidor.

tiene dos opciones para obtener la información de los casos EchoHandler:

  1. tienda la conexión como una propiedad del servidor (añadir server.conn = conn antes de llamar server_forever()) y luego acceder a esa propiedad en EchoHandler.handler través self.server.conn .
  2. Puede sobrescribir el servidor finish_request y asignar el valor allí (deberá pasarlo al constructor de EchoHandler y sobrescribir EchoHandler .__ init__). Esa es una solución muy desordenada y prácticamente requiere que guarde la conexión en el servidor de todos modos.

Mi optionon de su mejor apuesta:

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 
+0

que funciona muy bien, gracias! – Jesse

9

Mark T tiene que decir lo siguiente en el archivo de la lista de pitón

En la clase de controlador, self.server se refiere al objeto de servidor, así que subclase el servidor e invalide init para tomar cualquier parámetro de servidor adicional y guárdelos como variables de instancia.


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 

+0

¿Por qué no hacer 'super() .__ init __ (...)' en su lugar en 'MyServer .__ init__'? –

+1

Las clases en los módulos SocketServer son clases "antiguas". El superconstructor tiene que ser llamado de esta manera. Vea aquí: https://stackoverflow.com/questions/11527921/python-inheriting-from-old-style-classes – aramaki

0

Otra forma, que yo creo más Pythonic, es hacer lo siguiente:

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) 

Ahora puede dar una ejemplo de su controlador a la TCPServer:

SocketServer.ForkingTCPServer(('10.0.0.6', 4242), EchoHandler("aaa", "bbb")) 

El TCPServer normalmente crea una nueva instancia de EchoHandler por solicitud, pero en este caso, el __call__ método será llamado en lugar del constructor (que ya es una instancia.)

En el método llamada, que explícitamente hacer una copia de la EchoHandler actual y pasarlo al constructor de la superclase para ajustarse a la lógica original de "instancia de un administrador por solicitud".

Vale la pena echar un vistazo al módulo SocketServer a entender lo que sucede aquí: https://github.com/python/cpython/blob/2.7/Lib/SocketServer.py

Cuestiones relacionadas