作为对通信协议(EDIFACT MSCONS)进行解码的程序的一部分,我有一个类,它为我提供消息的下一个“段”。段由撇号“'”分隔。“'”后面可能有换行符,也可能没有。 下面是该类的代码:
class SegmentGenerator:
def __init__(self, filename):
try:
fh = open(filename)
except IOError:
print ("Error: file " + filename + " not found!")
sys.exit(2)
lines=[]
for line in fh:
line = line.rstrip()
lines.append(line)
if len(lines) == 1:
msg = lines[0]
else:
msg = ''
for line in lines:
msg = msg + line.rstrip()
self.segments=msg.split("'")
self.iterator=iter(self.segments)
def next(self):
try:
return next(self.iterator)
except StopIteration:
return None
if __name__ == '__main__': #testing only
sg = SegmentGenerator('MSCONS_21X000000001333E_20X-SUD-STROUM-M_20180807_000026404801.txt')
for i in range(210436):
if i > 8940:
break
print(sg.next())
要了解文件的外观,请参见以下摘录:
UNB+UNOC:3+21X000000001333E:020+20X-SUD-STROUM-M:020+180807:1400+000026404801++TL'UNH+000026404802+MSCONS:D:04B:UN:1.0'BGM+7+000026404802+9'DTM+137:201808071400:203'RFF+AGI:6HYR67925RZUD_000000257860_00_E27'NAD+MS+21X000000001333E::020'NAD+MR+20X-SUD-STROUM-M::020'UNS+D'NAD+DP'LOC+172+LU0000010496200000000000050287886::89'DTM+163:201701010000?+01:303'DTM+164:201702010000?+01:303'LIN+1'PIA+5+1-1?:1.29.0:SRW'QTY+220:9.600'DTM+163:201701010000?+01:303'DTM+164:201701010015?+01:303'QTY+220:10.400'DTM+163:201701010015?+01:303'DTM+164:201701010030?+01:303'QTY+220:10.400'DTM+163:201701010030?+01:303'DTM+164:201701010045?+01:303'QTY+220:10.400'DTM+163:201701010045?+01:303'DTM+164:201701010100?+01:303'QTY+220:10.400'DTM+163:201701010100?+01:303'DTM+164:201701010115?+01:303'QTY+220:10.400'DTM+163:201701010115?+01:303'DTM+164:201701010130?+01:303'QTY+220:10.400'DTM+163:201701010130?+01:303'DTM+164:201701010145?+01:303'QTY+220:10.400'DTM+163:201701010145?+01:303'DTM+164:201701010200?+01:303'QTY+220:11.200'DTM+163:201701010200?+01:303' ...
我遇到问题的文件有210000个这样的段。我测试了代码,一切正常。段的列表是完整的,我得到了一个又一个正确的段,直到列表结束。你知道吗
我使用这些段作为statemachine的输入,statemachine从SegmentGenerator的实例中获取新的段。你知道吗
以下是摘录:
def DTMstarttransition(self,segment):
match=re.search('DTM\+(.*?):(.*?):(.*?)($|\+.*|:.*)',segment)
if match:
if match.group(1) == '164':
self.currentendtime=self.dateConvert(match.group(2),match.group(3))
return('DTMend',self.sg.next())
return('Error',segment + "\nExpected DTM segment didn't match")
该方法返回下一个状态和下一个段的名称sg.下一个(),sg是SegmentGenerator的实例。你知道吗
但是在第8942段sg.下一个()不会给我下一个片段,而是片段列表的最后一个!你知道吗
我跟踪了函数调用(使用autologging模块):
TRACE:segmentgenerator.SegmentGenerator:next:CALL *() **{}
TRACE:segmentgenerator.SegmentGenerator:next:RETURN 'DTM+164:201702010000?+01:303'
TRACE:__main__.MSCONSparser:QTYtransition:RETURN ('DTMstart', 'DTM+164:201702010000?+01:303')
TRACE:__main__.MSCONSparser:DTMstarttransition:CALL *('DTM+164:201702010000?+01:303',) **{}
TRACE:__main__.MSCONSparser:dateConvert:CALL *('201702010000?+01', '303') **{}
TRACE:__main__.MSCONSparser:dateConvert:RETURN datetime.datetime(2017, 2, 1, 0, 0)
TRACE:segmentgenerator.SegmentGenerator:next:CALL *() **{}
TRACE:segmentgenerator.SegmentGenerator:next:RETURN 'UNT+17872+000026404802'
TRACE:__main__.MSCONSparser:DTMstarttransition:RETURN ('DTMend', 'UNT+17872+000026404802')
TRACE:__main__.MSCONSparser:DTMendtransition:CALL *('UNT+17872+000026404802',) **{}
UNT+。。。不是下一段,应该是LIN段。 但这怎么可能呢?为什么SegmentGenerator在我用它的模块中的main函数测试它时能工作,而在从另一个模块调用了数千次之后却不能正常工作?你知道吗
所有的片段从头到尾都在那里。我可以从口译员那里核实,因为sg段程序停止后保持可用。伦(sg段)是210435,但我的程序在8942后停止。所以这显然是迭代器的问题。你知道吗
这些文件(3个python文件和数据示例)可以在分支“next”的Github上找到,如果您想测试整个过程的话。你知道吗
结果是一段'DTM+164:201702010000?+01:303'在文件的更深处第二次存在,而且确实是一个UTM段。所以问题在于协议状态本身和迭代器工作正常。 很抱歉,我的错误假设打扰了你。谢谢你的帮助!你知道吗
我认为在你的数据文件中有可能有一个双撇号',在第8942撇号附近。你知道吗
在这种情况下,您的代码将继续读取整个文件,读取所有210435段。你知道吗
但是如果您有测试
sg.next()
结果的条件,那么在第8942次迭代中这将是错误的,我猜这将导致您的程序中止。你知道吗例如:
如果我完全错了,那么我会有兴趣看看这个的行为:-len和迭代应该相等。你知道吗
相关问题 更多 >
编程相关推荐