2013-06-26 46 views
1

我越來越想讀CSV計數時,出現以下錯誤:錯誤CSV:強迫爲Unicode:需要字符串或緩衝區,S3BotoStorageFile發現

>脅迫爲Unicode:需要字符串或緩衝區,S3BotoStorageFile發現

import csv 

class CSV: 
    def __init__(self, file=None): 
     self.file = file 

    def read_file(self): 
     data = [] 
     file_read = read_file(self.file) 
     return file_read 

    def get_row_count(self): 
     return len(self.read_file()) 

    def get_column_count(self): 
     new_data = self.read_file() 
     return len(new_data[0]) 

    def get_data(self, rows=1): 
     data = self.read_file() 
     return data[:rows] 

def read_file(self): 
    with open(self.file, 'r') as f: 
     data = [row for row in csv.reader(f.read().splitlines())] 
    return data 

請問該如何解決?

+1

你可以添加堆棧跟蹤嗎? – Wolph

+0

'.splitlines()'返回一個列表。 csv.reader不需要列表我相信 –

+1

沒有必要添加任何'csv.reader(f)'就夠​​了! – zmo

回答

4

好吧,讀完你的代碼後,我的第一反應是OMG!他有多少人打開那個糟糕的文件?

這是你的類的新版本

class CSV: 
    def __init__(self, file=None): 
     self.file = file 
     with open(self.file, 'r') as f: 
      self.data = [row for row in csv.reader(f)] 

    def get_row_count(self): 
     return len(self.data) 

    def get_column_count(self): 
     return len(self.data[0]) 

    def get_data(self, rows=1): 
     return self.data 

我也是固定的csv.reader()處理。它接受一個文件對象,不需要.read().read().splitlines(),它只會導致錯誤。這可能是它失敗的原因。

好吧,根據您的說法,您正在使用AWS,並且您的文件不是文件的字符串路徑,而是文件對象。所以你不需要open()部分。您可能需要修改您的代碼,以便它如下:

class CSV: 
    def __init__(self, f=None): 
     self.file = f 
     if isinstance(self.file, str): # if the file is a string, it's a path that has to be opened 
      with open(self.file, 'r') as f: 
       self.data = [row for row in csv.reader(f)] 
     elif isinstance(self.file, File) or isinstance(self.file, file): # if that's a file object, no need to open 
      self.data = [row for row in csv.reader(self.file)] 
     else: # otherwise, I don't know what to do, so aaaaaaaargh! 
      raise Exception("File object type unknown: %s %s" % (type(file), file,)) 

    def get_row_count(self): 
     return len(self.data) 

    def get_column_count(self): 
     return len(self.data[0]) 

    def get_data(self, rows=1): 
     return self.data 

讀S3BotoStorage.py的S3BotoStorage類從django.core.files.base.File,從django.core.files繼承繼承。 utils.FileProxyMixin,它是全局python file類的屬性的組合。

因此,File對象不是file的實例,但它具有兼容的接口。因此,在前面的代碼中,我測試了self.file是否爲str,那麼它應該是我們的路徑open(),因此我們得到file()並解析它。否則,self.fileFile對象或file()對象,我們只需要解析它。如果這兩者都不是,那麼這是一個錯誤,我們將除外。

+0

謝謝@zmo真的很有用:)非常酷。我仍然得到強制轉換爲Unicode的錯誤:需要字符串或緩衝區,現在在此行上找到FieldFile:使用open(self.file,'r')作爲f: – GrantU

+0

'File'從哪裏來?是從Python導入? – GrantU

+1

你的情況,'文件'對象是'從django.core.files.base導入文件'(參見[S3BotoStorage.py](https://bitbucket.org/madssj/django-storages/src/2930ca5815ca/S3BotoStorage .py))否則它來自[django.core.files.utils.FileProxyMixin](https://github.com/django/django/blob/master/django/core/files/utils.py),這是一個文件對象屬性的組成。 – zmo

相關問題