Como modifico variáveis ​​na instância do servidor SocketServer de dentro de uma instância do manipulador RequestHandler em Python?

StackOverflow https://stackoverflow.com/questions/3868132

Pergunta

Aqui está o código em questão:

  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()

Cada vez que chega uma nova solicitação, a saída que recebo é False seguido pela True.O que eu quero é False seguido pela True pela primeira vez, e True seguido pela True daqui em diante.

Por que as modificações que fiz na variável na instância do servidor não persistem fora do escopo do manipulador? handle() função?

ATUALIZADA:

Então, tento usar variáveis ​​globais para conseguir o que desejo:

  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()

E ainda não funciona, ou seja,produz a mesma saída de antes.Alguém poderia me dizer onde estou errando?

Foi útil?

Solução

A bifurcação cria um novo processo, portanto você não pode modificar as variáveis ​​do servidor no processo original.Experimente o ThreadingTCPServer:

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()

Outras dicas

Seu problema é que SocketServer.ForkingMixin cria um novo processo para cada solicitação.Portanto, toda vez que uma nova solicitação chega, todas as suas variáveis ​​são redefinidas para seu estado padrão.Então, essencialmente, não importa o que você atribua a self.server.loaded, ele será redefinido na próxima solicitação.É também por isso que os globais não funcionam.

Se você precisa que uma variável persista entre as solicitações, é melhor escrever esses dados em algum lugar mais, er, persistente =).Essencialmente, parece que você está tentando resolver o problema de manter variáveis ​​de sessão.Há um milhão e uma maneiras de fazer isso e dependendo da sua situação, uma forma pode ser mais pertinente que outra.Eu recomendo fortemente observar como outros aplicativos SocketServer baseados em Python fazem isso.

Basta fazer uma rápida pesquisa no Google para obter um código semelhante ao seu:"filetype:py SocketServer ForkingMixIn" (um dos primeiros resultados é CherryPy, que eu recomendo fortemente).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top