2010-01-03 23 views
0

我在讀取和處理來自服務器的數據時遇到問題。我花了幾個小時來調試它,似乎問題與服務器沒有任何關係,但實際上只是我的一個for循環的問題。如果沒有真正看到服務器的數據,很難解釋這一點,但我會盡我所能解釋這一點。從隊列中的數據循環迭代的問題

基本上我有一臺服務器,當我發送一個命令時,它會依次返回5個不同的XML字符串。我的程序將這些數據解析爲Python字典並將它們存儲在不同的類屬性中。由於TCP是一個流,我通常不會單獨收到每個字符串。通常會發生的是我會收到第一個字符串,然後接下來的4個字符串以2個爲一組。因此,通常會有3個不同的for循環迭代。但是,最後一個字符串無法處理並存儲在屬性中。以下是包含for循環的邏輯:

def xmlParser(self, newData): 
    print newData 
    for string in newData: 
     if 'a' in string: 
      print 'string1 being processed' 
      xmlToDictionary(string, 'string1') 
     elif 'b' in string: 
      print 'string2 being processed' 
      xmlToDictionary(string, 'string2') 
     elif 'c' in string: 
      print 'string3 being processed' 
      xmlToDictionary(string, 'string3') 
     elif 'd' in string: 
      print 'string4 being processed' 
      xmlToDictionary(string, 'string4') 
     elif 'e' in string: 
      print 'string5 being processed' 
      xmlToDictionary(string, 'string5') 

打印語句僅用於調試目的。我對沒有被處理的最後一個字符串的第一反應是它根本沒有被接收。但是,通過打印newData,我可以驗證所有字符串都已收到併發送到此函數。 newData是一個包含要處理的字符串的列表。對於3次不同的迭代,newData看起來像這樣

newData = ['string1'] 
newData = ['string2', 'string3'] 
newData = ['string4', 'string5'] 

其「STRING5」未加工的,我不相信,因爲在xmlToDictionary被提出(),因爲字符串「STRING5是一個例外的其未處理「不打印。如果我在函數中包含一個else語句,那麼它也不會被執行。就好像for循環只是拒絕對最後一組數據執行第二次迭代。爲了進一步測試,我修改了服務器腳本,在'string4'之前發送'string5',令我驚訝的是,完全解決了問題並導致'string5'被處理並存儲爲字典。在這種情況下,newData看上去像這樣

newData = ['string1'] 
newData = ['string2', 'string3', 'string5'] 
newData = ['string4'] 

我也試圖修改服務器腳本停止發送「串,4」完全。這也成功地允許'string5'被處理。 for循環只進行兩次迭代和newData這個樣子

newData = ['string1'] 
newData = ['string2', 'string3', 'string5'] 

我試圖把所有這些彙集成確定是什麼問題,但我完全糊塗了。我從來沒有遇到過這樣的事情。如果我不能提出解決方案,我會讓腳本在'string4'之前發送'string5',或者我可以簡單地將服務器上的所有字符串組合起來,並將它作爲一個大字符串發送。無論如何,我仍然想確定這裏發生了什麼,因爲這可能表明我的計劃存在更深層次的問題。

+0

如果你打算離開調試打印語句,怎麼樣說出他們爲你輸出的內容? xmlParser調用了多少次? – Kylotan 2010-01-03 14:11:03

+0

對不起,我試圖弄清楚newData打印語句輸出的是什麼,以及for循環中沒有工作的唯一打印語句是最後一個。我沒有解釋清楚。這是一個很奇怪的問題,我自己並沒有真正理解它。如果我在xmlToDictionary()函數之後將每個打印語句放在for循環中,我很可能早就解決了這個問題。 – HoboMo 2010-01-03 17:40:43

回答

1

嗯,這個一個stumper。特別是因爲你沒有發佈真正的代碼,而是你自己的代碼應該如何工作的概念。由於這個概念沒有錯,所以你的例子沒有任何問題。

不過,我抄襲了你的代碼,然後試圖擾亂它以得到你的結果。我認爲最有可能的罪魁禍首是你的代碼中發生了一些不希望的副作用,這些副作用是處理string4的。您的描述聽起來非常像在列表被迭代時修改列表時發生的情況。這裏有一個例子,將導致您所描述的具體行爲:

elif 'd' in string: 
    print 'string4 being processed' 
    # undesirable side effect occurs here 
    newData.remove(string) 
    xmlToDictionary(string, 'string4') 

嘗試發送,例如[串,4,字符串1]的順序,看看是否字符串1獲得通過。如果不是這樣,那麼很可能會有一些副作用來自這段代碼。

+0

天才。我只是做了另一輪測試,我認爲你對string4的處理存在問題是正確的。它與修改newData沒有任何關係(我從經驗中知道總是使用列表解析來處理這類事情)。但我嘗試在string4之前和之後添加字符串以測試您的想法,並且string4之後的每個字符串都無法處理。我在異常處理程序中包裝了xmlToDictionary(string,'string4')來驗證這一點。所以這個功能似乎失敗了(仍然必須弄清楚爲什麼),並暫停進一步處理。再次感謝! – HoboMo 2010-01-03 16:49:04

3

「由於TCP是一個流,我通常不接受單獨的每個字符串」

不能可靠和可預測分別接收它們。 TCP使事物成爲一個單一的數據流。這就是TCP/IP 必須做的。它必須進行緩衝才能創建一個「數據流」,而不管你在每一端嘗試發送或接收「分開」的東西。單獨使用TCP/IP時沒有意義。

您必須使用字符串的某些功能在您的最後分解字符串。句法。標點。一些東西。

通常,我們所做的是將5個XML字符串合併爲一個XML消息。

<message> 
    <string1>...</string1> 
    <string2>...</string2> 
    <string3>...</string3> 
    <string4>...</string4> 
    <string5>...</string5> 
</message>   

解析一條消息,找到你的五個字符串。它更簡單。它符合TCP/IP實際工作的方式。

1

我只是想你的代碼,結果如下:

def xmlParser(newData): 
    for string in newData: 
     print string 
     if 'a' in string: 
      print 'string1 being processed' 
     elif 'b' in string: 
      print 'string2 being processed' 
     # ... 
     elif 'e' in string: 
      print 'string5 being processed' 

newData = ['string1'] 
xmlParser(newData) 
newData = ['string2', 'string3'] 
xmlParser(newData) 
newData = ['string4', 'string5'] 
xmlParser(newData) 

這裏是輸出:

$ python test.py 
string1 
string2 
string3 
string4 
string5 

循環將處理完全相同的所有元素,如果裏面有xmlToDictionary沒有異常拋出。如果您想驗證是否拋出異常,試試這個代碼:

def xmlParser(self, newData): 
    print newData 
    for string in newData: 
     try: 
      if 'a' in string: 
       print 'string1 being processed' 
       xmlToDictionary(string, 'string1') 
      # ... 
      elif 'e' in string: 
       print 'string5 being processed' 
       xmlToDictionary(string, 'string5') 
      except: 
      print "excetion error" 

也許測試條件是不是你想要什麼:

如果「a」的字符串:

希望我幫你