2010-01-03 87 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”的字符串:

希望我帮你