2013-01-15 48 views
1

这是我的代码,我用它来打开一个Excel工作表,然后返回每一行作为一个字符串列表(其中每个单元格是一个字符串)。该类返回一个列表,其中填充了与文件中的行数一样多的列表。所以50行将返回50个列表。为什么我的类不会返回列表迭代?

from xlrd import open_workbook 

class ExcelReadLines(object): 

    def __init__(self,path_to_file): 
     '''Accepts the Excel File''' 
     self.path_to_file = path_to_file 
     self.__work__() 


    def __work__(self): 
     self.full_file_as_read_lines = [] 
     self.book = open_workbook(self.path_to_file) 
     self.sheet = self.book.sheet_by_index(0) 

     for row_index in range(self.sheet.nrows): 
      single_read_lines = [] 
      for col_index in range(self.sheet.ncols): 
       cell_value_as_string = str(self.sheet.cell(row_index,col_index).value) 
       cell_value_stripped = cell_value_as_string.strip('u') 
       single_read_lines.append(cell_value_stripped) 
      self.full_file_as_read_lines.append(single_read_lines) 

     return self.full_file_as_read_lines 

但是当我运行:

for x in ExcelReader('excel_sheet'): print x 

我得到的错误信息:

class is not iterable 

回答

7

为了一类是迭代的,它需要有一个__iter__方法。

考虑:

class Foo(object): 
    def __init__(self,lst): 
     self.lst = lst 
    def __iter__(self): 
     return iter(self.lst) 

例如:

>>> class Foo(object): 
...  def __init__(self,lst): 
...   self.lst = lst 
...  def __iter__(self): 
...   return iter(self.lst) 
... 
>>> Foo([1,2,3]) 
<__main__.Foo object at 0xe9890> 
>>> for x in Foo([1,2,3]): print x 
... 
1 
2 
3 

你举的例子似乎将是作为发电机定好位好 - 我真的不明白的需要这里是一堂课:

def excel_reader(path_to_file): 
    book = open_workbook(path_to_file) 
    sheet = book.sheet_by_index(0) 

    for row_index in range(sheet.nrows): 
     single_read_lines = [] 
     for col_index in range(sheet.ncols): 
      cell_value_as_string = str(self.sheet.cell(row_index,col_index).value) 
      cell_value_stripped = cell_value_as_string.strip('u') 
      single_read_lines.append(cell_value_stripped) 
     yield single_read_lines 
+0

我环顾四周,这似乎是共识。但我不明白如何使用它来返回列表的列表。 – user1367204

2

你应该看看实现Python的special iterator methods

另外,请注意,您不应该命名方法__work__,因为它使用了神奇的方法语法,但实际上并不是真正的魔法方法。

1

这里有几个问题。

  1. 您的代码不会返回任何内容。您致电__work__,但不要返回该值。

  2. 即使这样做,这也无济于事,因为从__init__返回的东西不会使对象成为那件事。

  3. 你不想让你的对象成为列表无论如何,你只是想迭代它。

有关如何在Python中编写迭代器的简单示例,请参见this question

此外,你不应该在你的代码中使用双下划线三明治名称,如__work__。这种名称按照惯例保留供Python内部使用。

+0

我不明白你的第一点。我相信它确实会带来价值。 init调用工作方法,工作方法返回一个列表。 另外,我想列出一个列表,这样我可以按照算法对每个列表进行排序,并将每个列表放入一个存储桶或另一个存储桶中。 – user1367204

+2

@ user1367204 - 要从函数返回值,您需要'return'语句。而且,python不尊重从__init__返回的值。 – mgilson

0

除非我记错了,你是真正之后

def first_sheet(fname): 
    wb = xlrd.open_workbook(fname) 
    ws = wb.sheet_by_index(0) 
    for i in xrange(ws.nrows): 
     yield ws.row_values(i) # maybe strip 'u''s - but that looks a bit sus... (probably something to do with your `str`) 

list_of_rows = list(first_sheet('somefile.xls')) 

然后使用zip如果需要的话做任何换位......

相关问题