更Pythonic的迭代方式

3 投票
3 回答
526 浏览
提问于 2025-04-15 23:35

我正在使用一个商业软件的API中的模块。好消息是有一个Python模块,但坏消息是这个模块的用法不太符合Python的风格。

要遍历行,使用以下语法:

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

那么,有什么更符合Python风格的方法来处理这种情况呢?我考虑过创建一个一流的函数或生成器,并在其中封装对for循环的调用:

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

这样做确实有所改善,但感觉还是有点笨拙。有没有更符合Python风格的方法?我应该为table类型创建一个包装类吗?

3 个回答

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)

另外可以参考:迭代器类型

11

假设“Next”和“next”其中一个是打错了,其实它们是一样的,你可以使用内置的iter函数的一个不太常见的变体:

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

撰写回答