2013-04-01 31 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