2013-04-01 73 views
0

我遇到以下问题,我正在运行一些Python代码。它应该只是遍历一个列表,但它似乎在做一些奇怪而微妙的事情,我真的无法弄清楚。在连续运行时更改Python打印语句

from skimage.io import imread 

def addImageData(self): 
    for image in self.images: 
     print image.signatureId 
    for image in self.images: 
     print image.signatureId 
     imageNumber = str(image.signatureId).zfill(4) 
     filePath = self.imageDirectory + imageNumber + ".jpg" 
     image.construct(filePath) 

def construct(self, filePath): 
    self.imageData = imread(filePath, as_grey=True) 

其中imread来自skimage.io。 addImageData下的第一个for循环完美地工作,打印出一系列范围从1到600的数字。然而,第二个循环,当添加构造方法时,只需打印数字1直到遇到内存错误。我很诚实地不知道是什么造成了这种情况。思考?

当使用键盘中断,这是回溯:

File "rbm.py", line 22, in buildImages 
    self.addImageData() 
    File "rbm.py", line 41, in addImageData 
    image.construct(filePath) 
    File "rbm.py", line 61, in construct 
    self.imageData = imread(filePath, as_grey=True) 
    File "/usr/local/lib/python2.7/dist-packages/scikit_image-0.8.2-py2.7-linux-i686.egg/skimage/io/_io.py", line 142, in imread 
    img = rgb2grey(img) 
    File "/usr/local/lib/python2.7/dist-packages/scikit_image-0.8.2-py2.7-linux-i686.egg/skimage/color/colorconv.py", line 540, in rgb2gray 
    return _convert(gray_from_rgb, rgb[:, :, :3])[..., 0] 
    File "/usr/local/lib/python2.7/dist-packages/scikit_image-0.8.2-py2.7-linux-i686.egg/skimage/color/colorconv.py", line 339, in _convert 
    out = np.dot(matrix, arr) 

添加相关的所有代码下面self.images:

class TrainingImages: 
    def __init__(self, csvFile = "../train.csv", imageDirectory = "../images/"): 
     self.csvFile = csvFile 
     self.imageDirectory = imageDirectory 
     self.images = [] 

    def appendCsvLine(self, line): 
     '''Assumes the line is from a csv.reader object''' 
     signatureId = line[1] 
     if len(self.images) <= signatureId: 
      newImage = Image(signatureId) 
      self.images.append(newImage) 
      newImage.append(line) 
     else: 
      self.images[(signatureId-1)].append(line) 

    def buildImages(self): 
     with open(self.csvFile, 'rb') as strokeData: 
      reader = csv.reader(strokeData, delimiter=",") 
      for line in reader: 
       self.appendCsvLine(line) 
     self.addImageData() 
+0

我的猜测是无限递归。如果你通过一个KeyboardInterrupt来停止程序,你的回溯看起来像什么? –

+1

是否打印数字1然后“挂起”? –

+0

不,在打出内存错误之前,它会多次打印数字1。 –

回答

1

感谢所有的评论人,他们是在非常有帮助搞清楚这一点,但是当这一切都说完了,这是一个非常奇怪的错误,但我发现了源,并希望分享它。

在函数appendCsvLine我显然是比较一个字符串与整数。无论实际在条目中的对象是什么,csv.reader类的结果总是一个字符串。我隐含的假设是,如果我在做比较字符串和整数python会引发valueError的愚蠢行为。显然情况并非如此。

def appendCsvLine(self, line): 
    '''Assumes the line is from a csv.reader object''' 
    signatureId = int(line[1]) 
    if len(self.images) <= signatureId: 
     newImage = Image(signatureId) 
     self.images.append(newImage) 
     newImage.append(line) 
    else: 
     self.images[(signatureId-1)].append(line) 

这令人难以置信的小改变固定我的代码,这是一个非常困难的bug跟踪并发现。这个问题或许可以最好通过下面的代码片段来解释:

>>> "100" > 99999999999999999999999 
True 

至于由我注意到这个问题的方法,我第一次实现将行print [img.signatureID for img in self.images]我的代码的EOL的建议。我发现它打印出一大串1的数组,然后是大数的2,然后是大数的3。等等。

然后我开始看看图像所在的那段代码实际上构建并在appendCsvLine函数的if和else下放置简单的打印行。我意识到程序从未到达else语句,并从那里测试了if语句的输出,然后意识到将signatureId显式转换为整数可以解决问题。然后在用csvl.reader在shell中运行一些测试并在python中比较字符串和整数后,我意识到了我的错误。

+0

你是如何找出问题的?在这里,我认为*方法*比结果更重要。 :)无意义的比较在Python 3中引发了一个异常,这很好。 – EOL

+0

+1为更一般的方法描述。简单的可变印刷有时可以大大减少错误。 – EOL