Как изменить переменные в экземпляре сервера SocketServer из экземпляра обработчика RequestHandler в Python? - PullRequest
3 голосов
/ 06 октября 2010

Вот код, о котором идет речь:

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

Каждый раз, когда приходит новый запрос, я получаю вывод False, за которым следует True.То, что я хочу, это False, за которым следует True в первый раз, и True с последующим True впредь.

Почему изменения, внесенные в переменную в экземпляре сервера, не сохраняются вне области действия handle() обработчика?

ОБНОВЛЕНО:

Итак, я пытаюсь использовать глобальные переменные для достижения желаемого:

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

И он все еще не работает, то есть выдает тот же результат, что и раньше.Может кто-нибудь сказать мне, где я иду не так?

Ответы [ 2 ]

3 голосов
/ 06 октября 2010

Форкинг создает новый процесс, поэтому вы не можете изменять переменные сервера в исходном процессе. Попробуйте использовать 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()
2 голосов
/ 06 октября 2010

Ваша проблема в том, что SocketServer.ForkingMixin создает новый процесс для каждого запроса.Поэтому каждый раз, когда поступает новый запрос, все ваши переменные возвращаются в состояние по умолчанию.Таким образом, независимо от того, что вы присваиваете self.server.loaded, он будет сброшен при следующем запросе.По этой же причине глобальные переменные не будут работать.

Если вам нужна переменная для сохранения между запросами, лучше записать эти данные куда-нибудь еще, например, постоянные =).По сути, похоже, что вы пытаетесь решить проблему сохранения переменных сеанса.Есть миллион и один способ сделать это, и в зависимости от вашей ситуации, один способ может быть более подходящим, чем другой.Я настоятельно рекомендую посмотреть, как это делают другие приложения на базе Python SocketServer.

Просто сделайте быстрый поиск кода, похожего на ваш: "filetype: py SocketServer ForkingMixIn" (одним из первых результатов является CherryPy, который я очень рекомендуюрекомендую посмотреть).

...