2011-07-29 12 views
13

Chciałbym przekazać moje połączenie z bazą danych do klasy EchoHandler, jednak nie mogę wymyślić, jak to zrobić lub uzyskać dostęp do klasy EchoHandler w ogóle .Z python socketserver jak mogę przekazać zmienną do konstruktora klasy obsługi

 

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

Odpowiedz

23

Niestety, naprawdę nie ma łatwego dostępu do modułów obsługi bezpośrednio spoza serwera.

Masz dwie opcje, aby uzyskać informacje na instancje EchoHandler:

  1. Store połączenie jako właściwości serwera (Add server.conn = conn przed wywołaniem server_forever()), a następnie uzyskać dostęp do nieruchomości w EchoHandler.handler przez self.server.conn .
  2. Możesz zastąpić serwer finish_request i przypisać tam wartość (musisz przekazać go do konstruktora EchoHandler i nadpisać EchoHandler .__ init__). Jest to rozwiązanie o dużej niezawodności i pewności co do tego, że trzeba przechowywać połączenie na serwerze.

Moja optionon z Najprościej:

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

To działa pięknie, dziękujemy! – Jesse

9

Mark T ma następujący powiedzieć o archiwum listy python

W klasie handler, self.server odnosi się do obiektu serwera, więc podklasa serwer i nadpisanie init, aby wziąć dodatkowe parametry serwera i zapisać je jako zmienne instancji.


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

Dlaczego nie zrobić 'super() .__ init __ (...)' zamiast w 'MyServer .__ init__'? –

+1

Klasy w modułach SocketServer są klasami "starego stylu". Super-konstruktor musi zostać nazwany w ten sposób. Zobacz tutaj: https://stackoverflow.com/questions/11527921/python-inheriting-from-old-style-classes – aramaki

0

Innym sposobem, że wierzę bardziej pythonic jest wykonanie następujących czynności:

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) 

Można teraz podać instancji swojego przewodnika do tcpserver:

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

TCPServer zwykle tworzy nowe wystąpienie EchoHandler na żądanie, ale w tym przypadku, __call__ metoda będzie wywoływana zamiast konstruktora (jest już instancją.)

W wezwanie metodzie jawnie zrobić kopię aktualnego EchoHandler i przekazać go do super konstruktora w celu dostosowania się do oryginalna logika "instancji jednego użytkownika na żądanie".

Warto zaglądając do modułu SocketServer aby zrozumieć, co się dzieje tutaj: https://github.com/python/cpython/blob/2.7/Lib/SocketServer.py

Powiązane problemy