5

.fetchone()while ループを呼び出すだけでなく、次のジェネレーター関数を作成する利点はありますか? もしそうなら、その利点は何ですか?

ありがとう。

def testf2():
    db = connectToMysqlDB(None)

    sql_statement = " ".join([
        "select d.* ",
        "from dr_snapshot d ",
        "order by d.PremiseID asc, d.last_read asc; "])

    sel_cur = db.cursor()
    rc = sel_cur.execute(sql_statement)

    loop_ok = True
    while loop_ok:
        meter_row = sel_cur.fetchone()
        if meter_row:
            yield meter_row
        else:
            loop_ok = False

    yield None

for read_val in testf2():
   print(read_val)
   #Perform something useful other than print.

('610159000', 6, datetime.datetime(2012, 7, 25, 23, 0), 431900L, 80598726L)
('610160000', 6, datetime.datetime(2012, 7, 25, 23, 0), 101200L, 80581200L)
None
4

3 に答える 3

5

いいえ。機能的には同じですが、コードを再利用したい場合は、ジェネレーターにラップする利点があります。たとえば、ジェネレーター ブロックでの読み取りが完了した後、接続/カーソルを閉じるコードを追加できます。カーソルが閉じられるように、これを上記のコードに追加することをお勧めします。

def testf2():
    try:
        db = connectToMysqlDB(None)

        sql_statement = " ".join([
            "select d.* ",
            "from dr_snapshot d ",
            "order by d.PremiseID asc, d.last_read asc; "])

        sel_cur = db.cursor()
        rc = sel_cur.execute(sql_statement)

        loop_ok = True
        while loop_ok:
            meter_row = sel_cur.fetchone()
            if meter_row:
                yield meter_row
            else:
                loop_ok = False
    except ProgrammingError:
        print "Tried to read a cursor after it was already closed"
    finally:
        sel_cur.close()

接続管理を 1 か所で行うだけでよいため、再利用が容易になります。

于 2012-07-27T17:18:05.323 に答える
4

私が正しかったように見えます.mySQLカーソル反復可能です( https://stackoverflow.com/a/1808414/138772 )。したがって、while ループの代わりにこれを行うことができます (ただし、データベースにアクセスするコードをジェネレーター関数内に配置するというアイデアが気に入っているので、そのままにしておいてください)。

for meter_row in sel_cur:
    yield meter_row

また、おそらくその final は必要ないことに注意してくださいyield None。例外は、反復子出力のStopIteration枯渇を示すためにfor使用され、ループがループを停止するフラグとして使用するものであるため、出力の最後にそれを含めるyield NoneことNoneで、実際の利益は得られません。

于 2012-07-27T17:22:18.177 に答える
0

ジェネレーターを使用すると、既存のコードで結果を使用する際の柔軟性がさらに高まります。たとえば、csv.writer writerows関数に直接渡すことができます。

于 2012-07-27T17:35:51.520 に答える