More pythonic way to iterate
I am using a module that is part of a commercial software API. The good news is there is a python module - the bad news is that its pretty unpythonic.
To iterate over rows, the follwoing syntax is used:
cursor = gp.getcursor(table)
row = cursor.next()
while row:
#do something with row
row = cursor.next()
What is the most pythonic way to deal with this situation? I have considered creat开发者_运维知识库ing a first class function/generator and wrapping calls to a for loop in it:
def cursor_iterator(cursor):
row = cursor.next()
while row:
yield row
row = cursor.next()
[...]
cursor = gp.getcursor(table)
for row in cursor_iterator(cursor):
# do something with row
This is an improvement, but feels a little clumsy. Is there a more pythonic approach? Should I create a wrapper class around the table
type?
Assuming that one of Next and next is a typo and they're both the same, you can use the not-so-well-known variant of the built-in iter function:
for row in iter(cursor.next, None):
<do something>
You could create a custom wrapper like:
class Table(object):
def __init__(self, gp, table):
self.gp = gp
self.table = table
self.cursor = None
def __iter__(self):
self.cursor = self.gp.getcursor(self.table)
return self
def next(self):
n = self.cursor.next()
if not n:
raise StopIteration()
return n
and then:
for row in Table(gp, table)
See also: Iterator Types
The best way is to use a Python iterator interface around the table
object, imho:
class Table(object):
def __init__(self, table):
self.table = table
def rows(self):
cursor = gp.get_cursor(self.table)
row = cursor.Next()
while row:
yield row
row = cursor.next()
Now you just call:
my_table = Table(t)
for row in my_table.rows():
# do stuff with row
It's very readable, in my opinion.
精彩评论