如何在Python中的RequestHandler处理程序实例中修改SocketServer服务器实例中的变量?

时间:2010-10-05 22:05:49

标签: python python-2.7 sockets socketserver

以下是相关代码:

  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 个答案:

答案 0 :(得分:3)

Forking创建了一个新进程,因此您无法在原始进程中修改服务器的变量。请尝试使用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()

答案 1 :(得分:2)

您的问题是SocketServer.ForkingMixin为每个请求创建一个新进程。因此,每次新请求进入时,所有变量都会重置为默认状态。所以基本上无论你为self.server.loaded分配什么,它都会在下一个请求时重置。这也是全局变量不起作用的原因。

如果您需要在请求之间保留变量,那么最好将数据写入更多地方,呃,持久=)。从本质上讲,这听起来像是在试图解决保持会话变量的问题。有一百万种方法可以做到这一点,根据你的情况,一种方式可能比另一方式更相关。我强烈建议看看其他基于Python的SocketServer应用程序是如何做到的。

只需快速谷歌搜索类似的代码:“filetype:py SocketServer ForkingMixIn”(最初的结果之一是我强烈推荐的CherryPy)。