来自队列的数据的for循环迭代问题

时间:2010-01-03 13:03:30

标签: python loops for-loop

我在从服务器读取和处理数据时遇到问题。我花了几个小时调试这个问题似乎问题与服务器无关,但实际上只是我的一个for循环问题。如果没有真正看到来自服务器的数据,很难解释这一点,但我会尽力解释这一点。

基本上我有一个服务器,当我发送命令时,它会依次返回5个不同的XML字符串。我的程序将这些数据解析为Python字典,并将它们存储在不同的类属性中。由于TCP是一个流,我通常不会单独收到每个字符串。通常会发生的是我将收到第一个字符串,然后接收4个字符串中的接下来的4个字符串。因此,通常有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')

print语句仅用于调试目的。我对最后一个没有被处理的字符串的第一反应是它根本没有收到。但是,通过打印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']

我还尝试修改服务器脚本以完全停止发送'string4'。这也成功地允许'string5'被处理。 for循环只执行了两次迭代,newData看起来像这样

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

我试图把所有这些放在一起来确定问题是什么,但我完全糊涂了。我以前从未遇到过这样的事情。如果我不能提出解决方案,我会留下脚本在'string4'之前发送'string5',或者我可以简单地组合服务器上的所有字符串并将其作为一个大字符串发送。无论如何,我仍然想确定这里发生了什么,因为它可能表明我的程序存在更深层次的问题。

3 个答案:

答案 0 :(得分: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 :(得分: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':

希望我帮助你

答案 2 :(得分:1)

嗯,这个一个傻瓜。特别是因为你还没有发布真正的代码,而是你自己的代码应该如何工作的概念。由于这个概念没有任何问题,你的例子没有任何问题。

仍然,我复制了你的代码,然后试图扰乱它以获得你的结果。我认为最可能的罪魁祸首是你的代码处理string4会产生一些不良副作用。您的描述听起来非常类似于在迭代时修改列表时发生的情况。这是一个会导致您描述的确切行为的示例:

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

尝试发送类似[string4,string1]的序列,看看string1是否通过。如果没有,很有可能某种副作用来自这一块代码。