Comment puis-je modifier les variables dans l'instance de serveur SocketServer à partir d'une instance de gestionnaire RequestHandler en Python?
-
28-09-2019 - |
Question
Voici le code en question:
class Server(SocketServer.ForkingMixIn, SocketServer.TCPServer):
__slots__ = ("loaded")
class Handler(SocketServer.StreamRequestHandler):
def handle(self):
print self.server.loaded # Prints "False" at every call, why?
self.server.loaded = True
print self.server.loaded # Prints "True" at every call, obvious!
server = Server(('localhost', port), Handler)
server.loaded = False
while True:
server.handle_request()
Chaque fois qu'une nouvelle requête arrive, la sortie que je reçois est False
suivie True
. Ce que je veux est False
suivie True
la première fois, et True
suivi True
désormais.
Pourquoi ne sont pas les modifications que j'ai fait à la variable dans l'instance de serveur persistant en dehors du cadre de la fonction handle()
du gestionnaire?
MISE À JOUR:
Alors, j'essayer d'utiliser des variables globales pour obtenir ce que je veux:
loaded = False
class Server(SocketServer.ForkingMixIn, SocketServer.TCPServer):
pass
class Handler(SocketServer.StreamRequestHandler):
def handle(self):
global loaded
print loaded # Prints "False" at every call still, why?
loaded = True
print loaded # Prints "True" at every call, obvious!
def main():
server = Server(('localhost', 4444), Handler)
global loaded
loaded = False
while True:
server.handle_request()
if (__name__ == '__main__'):
main()
Et il ne fonctionne toujours pas, à savoir produit le même résultat que précédemment. Quelqu'un pourrait-il s'il vous plaît me dire où je vais mal?
La solution
Bifurquer crée un nouveau processus, de sorte que vous ne pouvez pas modifier les variables du serveur dans le processus original. Essayez le ThreadingTCPServer à la place:
import SocketServer
class Server(SocketServer.ThreadingTCPServer):
__slots__ = ("loaded")
class Handler(SocketServer.StreamRequestHandler):
def handle(self):
self.server.loaded = not self.server.loaded
print self.server.loaded # Alternates value at each new request now.
server = Server(('localhost',5000),Handler)
server.loaded = False
while True:
server.handle_request()
Autres conseils
Votre problème est que SocketServer.ForkingMixin crée un nouveau processus pour chaque demande. Par conséquent, chaque fois qu'une nouvelle demande vient de toutes vos variables sont remplacées remis dans leur état par défaut. Donc, pratiquement pas d'importance ce que vous attribuez à self.server.loaded il se remis à zéro à la demande suivante. C'est aussi pourquoi globals ne fonctionnera pas.
Si vous avez besoin d'une variable de persister entre les requêtes que vous feriez mieux écrire que des données quelque part plus, euh, = persistants). Pour l'essentiel, il semble que vous essayez de résoudre le problème de garder les variables de session. Il y a un million et une façons de le faire et en fonction de votre situation, d'une façon peut-être plus pertinente qu'une autre. Je vous recommande vivement de voir comment d'autres applications SocketServer en Python font.
Il suffit de faire un rapide Google pour un code similaire à la vôtre. « Filetype: py SocketServer ForkingMixIn » (l'un des premiers résultats est CherryPy que je recommande fortement à la recherche)