كيف يمكنني تعديل المتغيرات في مثيل SocketServer Server من داخل مثيل معالج requestHandler في Python؟
-
28-09-2019 - |
سؤال
إليك الرمز المعني:
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()
وما زال لا يعمل ، أي ينتج نفس الإخراج كما كان من قبل. هل يمكن لأي شخص أن يخبرني من فضلك أين أخطأ؟
المحلول
يقوم 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()
نصائح أخرى
مشكلتك هي أن SocketServer.ForkingMixin يخلق عملية جديدة لكل طلب. لذلك ، في كل مرة يأتي فيها طلب جديد في جميع متغيراتك ، يتم إعادة تعيينها إلى حالتها الافتراضية. لذا ، بغض النظر عن ما تقوم بتعيينه لـ Self.Server.Load ، سيتم إعادة تعيينه عند الطلب التالي. هذا هو السبب أيضًا في أن Globals لن تعمل.
إذا كنت بحاجة إلى متغير للاستمرار بين الطلبات ، فمن الأفضل أن تكتب تلك البيانات في مكان ما ، ER ، ثابت =). في الأساس ، يبدو أنك تحاول حل مشكلة الحفاظ على متغيرات الجلسة. هناك مليون وطرق واحدة للقيام بذلك واعتمادًا على وضعك ، قد تكون بطريقة ما أكثر أهمية من طريقة أخرى. أوصي بشدة بالبحث في كيفية قيام تطبيقات SocketServer الأخرى القائمة على Python.
ما عليك سوى القيام بـ Google سريعًا للحصول على رمز مشابه لك: "FileType: Py SocketServer ForkingMixin" (واحدة من النتائج الأولى هي Cherrypy التي أوصي بشدة بالنظر إليها).