この記事のポイント

  • generator遅延評価の設計整理をレビュー視点で体系理解できる
  • 状態管理、リソース開放、例外責務整理の技法を学べる
  • 実務でのgenerator利用文化を体系化できる
  • PlantUMLで依存構造と状態保持責任を可視化整理できる

そもそもgeneratorとは

Pythonのgeneratorは「イテレータを遅延生成する構造」です。
yield文を使うことで中断・再開可能な制御構造を提供します。

  • 全件リスト展開せず逐次処理
  • メモリ使用量抑制
  • 状態保持による中間処理省略
generator基本例

def count_up_to(n):
    i = 0
    while i < n:
        yield i
        i += 1

for num in count_up_to(5):
    print(num)
  • 各要素を順次生成
  • forループで自動的にnext()呼出

なぜこれをレビューするのか

generator設計は「状態保持責務が隠蔽されやすい」危険性を持ちます。
レビューアーは以下の整理視点を持つ必要があります。

レビューアー視点

  • generator内に副作用処理が混入していないか
  • リソース管理責務が漏洩していないか
  • 中断再開可能性が設計的に考慮されているか
  • イテレーション途中中断後の状態保持責務が破綻していないか
  • 例外制御が中断復帰不能になっていないか

開発者視点

  • 遅延評価のコスト構造を意識しきれない
  • yield内にDB・API呼出を埋め込みがち
  • finally開放責務を設計せず放置
  • for文に隠蔽され実態を軽視しがち

generator崩壊の典型設計臭

崩壊しやすいパターン
  • ファイル/DB接続をopenしたままyield
  • 外部API呼出を逐次yieldで遅延呼出
  • 例外発生時にfinally不在でリソース破棄漏れ
  • 状態更新含むyieldで中断不整合
  • ネストgeneratorで状態肥大化

崩壊例:リソース保持漏洩型

リソース漏洩例

def read_lines(file_path):
    f = open(file_path)
    for line in f:
        yield line
@Reviewer
ファイルオープン状態がyield外に保持されています。with構文併用で開放責任を整理してください。

問題点

  • イテレーション完了保証が前提
  • 中断時にファイルクローズ未保証

崩壊構造モデル:リソース漏洩構造

UML Diagram

generator設計整理の原則

以下の遅延評価設計文化が健全性維持に有効です。

① with構文融合文化

  • リソースopen → yield はwith内で閉じる

② yield前後責務明示文化

  • yield直前直後の副作用設計を明示

③ finally開放責務文化

  • 状態保持系は必ずfinally整理

④ 中断安全文化

  • for中断/例外発生時も設計上回復可能化

⑤ 状態更新分離文化

  • 状態変更はyield内に混入しない

改善例:with融合整理版

with整理版

def read_lines(file_path):
    with open(file_path) as f:
        for line in f:
            yield line
「with文化+yield責務分離文化」

レビューアーは「yield前後副作用文化」を徹底確認すると設計臭抑止できます。

改善構造モデル:リソース安全整理

UML Diagram

良くない実装例: ケース1(副作用混入)

副作用混入例

def process_items(items):
    for item in items:
        db.insert(item)
        yield item
@Reviewer
副作用(DB書込)がyield中に混在しています。副作用分離整理してください。

問題点

  • yield中断で処理保証崩壊
  • 副作用非再現性発生

改善例:副作用分離整理

副作用分離版

def generate_items(items):
    for item in items:
        yield item

def process_and_store(items):
    for item in generate_items(items):
        db.insert(item)
  • generatorは純粋データ流に限定
  • 副作用は呼出側に外出し整理

良くない実装例: ケース2(ネスト状態肥大)

ネスト肥大例

def nested_generator():
    for x in outer_source():
        for y in inner_source(x):
            yield transform(x, y)
@Reviewer
ネストyieldにより状態肥大が発生しています。段階分離整理してください。

問題点

  • 状態伝播負荷上昇
  • 再現検証困難化

改善例:段階分離整理版

段階分離版

def generate_outer():
    for x in outer_source():
        yield x

def generate_inner(x):
    for y in inner_source(x):
        yield y

def generate_combined():
    for x in generate_outer():
        for y in generate_inner(x):
            yield transform(x, y)
  • 各層を独立責務に分離整理
  • 読解・検証容易化

良くない実装例: ケース3(finally欠落)

finally欠落例

def resource_stream(resource):
    resource.connect()
    try:
        while True:
            yield resource.read()
    finally:
        resource.disconnect()
@Reviewer
finallyは正しいですがyield前のconnectが分離不全です。with文化整理を優先検討してください。

問題点

  • 入口責務も構造化未整理
  • 呼出構造依存が強い

改善例:contextmanager統合整理

context整理版

from contextlib import contextmanager

@contextmanager
def resource_manager(resource):
    resource.connect()
    try:
        yield resource
    finally:
        resource.disconnect()

def resource_stream(resource):
    with resource_manager(resource) as res:
        while True:
            yield res.read()
  • 初期化〜開放を構造統制化
  • 呼出側中断安全化

観点チェックリスト

まとめ

generator設計は「状態設計と副作用制御の訓練場」そのものです。
レビューアーは「副作用分離文化・リソース責務文化・中断安全文化」を育成指導することで、
保守可能性の高い堅牢な遅延評価設計を育てられます。