2010-06-05 52 views
3

我使用的模块是商业软件API的一部分。好消息是有一个python模块 - 坏消息是它非常不错。更多pythonic方式来迭代

遍历行时,follwoing语法用于:

cursor = gp.getcursor(table) 
row = cursor.next() 
while row: 
    #do something with row 
    row = cursor.next() 

什么是处理这种情况的最Python的方式?我也考虑创造一流的功能/发电机和它包装调用一个循环:

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 

这是一个进步,但感觉有点笨拙。是否有更多pythonic方法?我应该围绕table类型创建包装类吗?

+0

Mmmh'cursor.next()'看起来像你*可能*能够为光标中的行做': – 2010-06-05 10:56:35

+1

@Felix,nope。 'next'不会引发['StopIteration'](http://docs.python.org/library/exceptions.html#exceptions.StopIteration),所以在真正的数据之后,这只会使用'row'是'没有'。 – 2010-06-05 11:00:40

+0

@Felix King:差不多,但因为一个迭代器通过提高StopIteration信号来终止信号,所以'cursor in cursor:'中的行将遍历行,然后给出无限的'None'流。 – 2010-06-05 11:00:51

回答

11

假设下的一个旁边是一个拼写错误和他们都一样,你可以使用的不那么知名的变体内置ITER功能:

for row in iter(cursor.next, None): 
    <do something> 
+0

很好的回答!是的,功能是一样的(更糟糕的是,它们在某种程度上不区分大小写!)。 – fmark 2010-06-05 10:57:17

+0

非常优雅! – pygabriel 2010-06-05 11:57:35

1

的最好的方法是使用一个Python迭代器接口围绕table对象,恕我直言:

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() 

现在您只要致电:

my_table = Table(t) 
for row in my_table.rows(): 
    # do stuff with row 

在我看来,它非常易读。

2

您就可以创建一个定制的包装:

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 

然后:

for row in Table(gp, table) 

参见:Iterator Types

+0

我也喜欢这种方法。我可能会考虑以这种方式包装'gp',如果我需要包装不仅仅是光标迭代。 – fmark 2010-06-05 11:47:56