Более питонический способ повторения - PullRequest
3 голосов
/ 05 июня 2010

Я использую модуль, который является частью коммерческого программного обеспечения API. Хорошая новость в том, что есть модуль Python, плохая новость в том, что он довольно не пифоничен

Для итерации по строкам используется следующий синтаксис:

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

Какой самый питонический способ справиться с этой ситуацией? Я рассмотрел создание функции / генератора первого класса и упаковку вызовов для цикла 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

Это улучшение, но кажется немного неуклюжим. Есть ли более питонический подход? Должен ли я создать класс-оболочку для типа table?

Ответы [ 3 ]

11 голосов
/ 05 июня 2010

Предполагая, что один из следующих и следующий является опечаткой, и они оба одинаковы, вы можете использовать не очень известный вариант встроенной функции iter:

for row in iter(cursor.next, None):
    <do something>
2 голосов
/ 05 июня 2010

Вы можете создать пользовательскую оболочку, например:

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)

См. Также: Типы итераторов

1 голос
/ 05 июня 2010

Лучший способ - использовать интерфейс итератора Python вокруг объекта table, 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()

Теперь вы просто звоните:

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

На мой взгляд, он очень читабельный.

...