Reputation: 4797
Here is my code, I use it to open an excel sheet and then return each row as a list of strings (where each cell is a string). The class returns one list that is filled with as many lists as there are rows in the file. So 50 rows will return 50 lists.
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
But when I run:
for x in ExcelReader('excel_sheet'): print x
I get the error message:
class is not iterable
Upvotes: 1
Views: 167
Reputation: 142176
Unless I'm mistaken, what you're really after is
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'))
Then do any transposition using zip
if needs be...
Upvotes: 0
Reputation: 309939
In order for a class to be iterable, it needs to have an __iter__
method.
Consider:
class Foo(object):
def __init__(self,lst):
self.lst = lst
def __iter__(self):
return iter(self.lst)
example:
>>> 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
Your example seems like it would be a good bit better as a generator -- I don't really understand what the need is for a class here:
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
Upvotes: 7
Reputation: 251408
You have a few problems here.
Your code doesn't return anything. You call __work__
but don't return the value.
Even if it did, that wouldn't help, because returning something from __init__
doesn't make the object be that thing.
You don't want your object to be a list anyway, you just want to iterate over it.
See this question for a simple example of how to write an iterator in Python.
In addition, you shouldn't use double-underscore-sandwich names like __work__
in your code. That sort of name is by convention reserved for Python-internal use.
Upvotes: 1
Reputation: 29658
You should look into implementing Python's special iterator methods.
Also, note that you shouldn't name a method __work__
since it uses magic method syntax but isn't actually a real magic method.
Upvotes: 2