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
4

4 回答 4

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
于 2013-01-15T20:39:00.070 回答
2

您应该研究实现 Python 的特殊迭代器方法

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

于 2013-01-15T20:40:23.217 回答
1

你在这里有几个问题。

  1. 您的代码不返回任何内容。您调用__work__但不返回值。

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

  3. 无论如何,您都不希望您的对象成为列表,您只想对其进行迭代。

有关如何在 Python 中编写迭代器的简单示例,请参阅此问题。

此外,您不应像__work__在代码中那样使用双下划线三明治名称。按照惯例,这种名称是为 Python 内部使用而保留的。

于 2013-01-15T20:40:41.047 回答
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'))

然后使用zipif 需要进行任何换位...

于 2013-01-15T20:55:20.003 回答