麻烦在Python中迭代文件中的行

时间:2015-10-26 16:19:15

标签: python io iteration

我有一个类,它模拟使用距离矢量路由算法计算网络中路径的场景。该类具有属性map_file,该属性是描述网络中连接的文件的名称。以下是DVSimulator类的代码片段:

def populate_map(self):
    with open(self.map_file,'r') as f:
        for line in f:
            data = line.split()
            length_of_link = data[2]
            ...

有一个名为" test_map1"的文件。它看起来像这样:

A  B  2.1
B  C  1.2
A  C  1.0
C  D  1.5   

文件中的每一行都表示两个节点之间的连接。这里,节点A连接到节点B,距离为2.1,节点B连接到节点C,距离为1.2,等等。

这是我的pyunit TestDVSimulator类中的setUp()方法:

def setUp(self):
     self.split_horizon_simulator1 = dv_simulator.DVSimulator("test_map1",True)
     self.no_split_simulator1 = dv_simulator.DVSimulator("test_map1", False)
     self.split_horizon_simulator2 = dv_simulator.DVSimulator("test_map2",True)
     self.no_split_simulator2 = dv_simulator.DVSimulator("test_map2",True)

以下是TestDVSimulator类中test_populate_map()方法的代码片段:

 def test_populate_map(self):
     """Tests the populate_map() method in DVSimulator"""
     splitty1 = self.split_horizon_simulator1
     no_splitty1 = self.no_split_simulator1
     splitty2 = self.split_horizon_simulator2
     no_splitty2 = self.no_split_simulator2
     splitty1.populate_map()
     no_splitty1.populate_map()
     splitty2.populate_map()
     splitty2.populate_map()
     ...

现在,当我尝试使用上面显示的map_file对populate_map()方法进行单元测试时,出现以下错误消息:

ERROR: Tests the populate_map() method in DVSimulator
----------------------------------------------------------------------
Traceback (most recent call last):
  File "dv_simulator_test.py", line 28, in test_populate_map
    splitty1.populate_map()
  File "/home/grads/klepp/6760/DistanceVectorProject/dv_simulator.py", line 33, in populate_map
    length_of_link = data[2]
IndexError: list index out of range

但是,我知道文件中的每一行都有3个长度,所以data [2]绝对不会超出范围。有趣的是,如果编辑populate_map()方法如下:

 def populate_map(self):
     with open(self.map_file,'r') as f:
         for line in f.readlines():            
             print "line from map file: " + line
             data = line.split()
             print "data: " + str(data)
             print str(data[0])
             print str(data[1])
             print str(data[2])
             length_of_link = data[2]
             ...

输出如下:

line from map file: A B 2.1

data: ['A', 'B', '2.1']
A
B
2.1
line from map file: B C 1.2

data: ['B', 'C', '1.2']
B
C 
1.2
line from map file: A C 1.0

data: ['A', 'C', '1.0']
A
C
1.0
line from map file: C D 1.5

data: ['C', 'D', '1.5']
C
D
1.5
line from map file: 

data: []
EF
======================================================================
ERROR: Tests the populate_map() method in DVSimulator
----------------------------------------------------------------------
Traceback (most recent call last):
  File "dv_simulator_test.py", line 28, in test_populate_map
    splitty1.populate_map()
  File "/home/grads/klepp/6760/DistanceVectorProject/dv_simulator.py", line 30, in populate_map
    print str(data[0])
IndexError: list index out of range

也就是说,str(data [0])清楚地打印出一些值,实际上它连续四次打印出来,但后来它说数据[0]超出了范围。出于某种原因,代码似乎在遍历文件中的行并在每行上调用line.split()之前运行length_of_link = data [2]的代码行。

有谁知道出了什么问题以及如何解决这个问题?

以下是DVSimulator类中populate_map()方法的完整脚本:

#The DVSimulator class simulates a Distance Vector Routing scenario                                                                                        
import routingtable
import dv_router

class DVSimulator:

  def __init__(self, map_file, split_horizon,verbosity = False, test_destination=''):

     self.routers_dictionary = {}
     self.neighbors_dictionary  = {} #a dictionary of router:dict pairs where dict is a dictionary of router values keyed by their names                
     self.breakables = [] #string tuples of (router1, router2) signifying a link to break upon convergence                                              
     self.using_split_horizon = split_horizon
     self.map_file = map_file
     self.verbose = verbosity
     self.number_of_iterations = 0
     self.test_dest = test_destination

 def populate_map(self):

     with open(self.map_file,'r') as f:
         for line in f:

             print "line from map file: " + line
             data = line.split()
             print "data: " + str(data)
             print str(data[0])
             print str(data[1])
             print str(data[2])
             length_of_link = data[2]
             if len(data) == 4:
                 breakables.append((data[0],data[1]))
             router1 = data[0]
             router2 = data[1]
             neighbor_pair = [router1, router2]

             for each in neighbor_pair:
                 if each == router1:
                     other = router2
                 else:
                     other = router1
                 if each not in self.routers_dictionary:
                     self.routers_dictionary[each] = dv_router.DVRouter(each, self.using_split_horizon)
                     self.neighbors_dictionary[each] = {}
                     for router in self.routers_dictionary:
                         if router != other:
                             self.routers_dictionary[router].add_link(each)
                     self.routers_dictionary[each].routing_table.edit_distance_to(each, 0, each)
              for each in neighbor_pair:
                  if each == router1:
                      other = router2
                  else:
                      other = router1
                  self.routers_dictionary[each].add_link(other,length_of_link)
                  self.neighbors_dictionary[each][other] = self.routers_dictionary[other]

1 个答案:

答案 0 :(得分:0)

错误在于test_map1文件。在文件的末尾是一个空行。如果删除该行,代码将按预期运行。如建议的那样,if语句也可以正确添加到空白行的分支中。