2010-10-05 41 views
3

下面的代碼有問題:如何在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() 

,它仍然無法正常工作,即像以前那樣產生相同的輸出。任何人都可以告訴我哪裏出錯了嗎?

+0

從Python文檔:「如果一個名字被宣佈全球性的,那麼所有的引用和作業直接轉到包含模塊的全局名稱中間的範圍,否則,發現最裏面之外的所有變量範圍是只讀的(試圖寫入這樣一個變量只會在最內層的範圍內創建一個新的局部變量,而保持同名的外層變量不變)。所以,我認爲,我的問題歸結爲解決這個問題。 – 2010-10-05 22:15:54

+0

我認爲這可能與ForkingMixIn類有關。嘗試刪除ForkingMixIn基類,看看是否改變了任何東西。 – flashk 2010-10-05 22:38:50

+0

恩,試過了。沒有工作。我認爲問題是在兩次調用Handler實例之間共享相同的*可寫*範圍。 – 2010-10-05 23:10:27

回答

3

分叉會創建一個新進程,因此您無法在原始進程中修改服務器的變量。嘗試代替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() 
+0

哦,我明白了。我認爲這應該工作。但是,我沒有嘗試過。我只是在使用文件的進程之間共享變量,一切都很好。 – 2010-10-11 14:42:25

+0

如果可以接受,請不要忘記接受答案; ^) – 2010-10-11 16:22:29

2

你的問題是,SocketServer.ForkingMixin爲每個請求創建一個新的進程。因此,每當新請求進入時,所有變量都會重置爲其默認狀態。所以基本上不管你分配給self.server.loaded它將在下一個請求重置。這也是全局變得無法運行的原因。

如果你需要一個變量來保持請求之間的關係,你最好把數據寫在更多的地方,呃,持久=)。從本質上講,這聽起來像你正試圖解決保持會話變量的問題。有一種方法可以做到這一點,根據你的情況,一種方式可能比另一種方式更合適。我強烈建議查看其他基於Python的SocketServer應用程序如何執行此操作。

只要做一個類似於你的代碼的快速谷歌:「filetype:py SocketServer ForkingMixIn」(我強烈推薦查看第一個結果是CherryPy的其中一個結果)。