如何在Python中从RequestHandler处理程序实例中修改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 个回答
2
你的问题在于,SocketServer.ForkingMixin 每次处理请求时都会创建一个新进程。因此,每当有新请求到来时,所有的变量都会被重置为默认状态。所以,不管你把什么赋值给 self.server.loaded,它在下一个请求到来时都会被重置。这也是为什么全局变量不起作用的原因。
如果你需要一个变量在多个请求之间保持不变,最好把这些数据存储在一个更“持久”的地方。实际上,听起来你是在尝试解决保持会话变量的问题。有很多种方法可以做到这一点,根据你的具体情况,有些方法可能更合适。我强烈建议你看看其他基于 Python 的 SocketServer 应用是怎么做的。
你可以快速在谷歌上搜索类似的代码:“filetype:py SocketServer ForkingMixIn”(搜索结果中有一个是 CherryPy,我非常推荐你去看看)。
4
分叉(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()