\

Pythonのyieldfinallyを組み合わせた関数の返し値(ジェネレータ)は直接nextに渡してはならない。以下にその理由と例を示します。

def yielder():
    try:
        print('yielder setup')
        yield 'text'
    finally:
        print('yielder teardown')

def f(text):
    print(text)

for y in yielder():
    f(y)

上記のコードを実行すると、出力は以下のようになります。

yielder setup
text
yielder teardown

しかし、nextを1回しか呼び出さないような使い方をすると、yielder setuptextのみが出力され、yielder teardownは呼ばれません。これは、finallyブロックが実行されないためです。

この問題を解決するためには、finallyを使用してteardownが呼ばれるようにすることができます。しかし、この関数を呼び出すときには注意が必要です。以下にその例を示します。

def yielder_with_finally():
    try:
        print('yielder setup')
        yield 'text'
    finally:
        print('yielder teardown')

def f(text):
    print(text)

for y in yielder_with_finally():
    f(y)

上記のコードを実行すると、出力は以下のようになります。

yielder setup
text
yielder teardown

しかし、nextを使用してジェネレータを呼び出すと、yielder setupyielder teardowntextの順に出力され、予期せぬ実行順序になってしまいます。

以上のように、Pythonのyieldfinallyを組み合わせる際には注意が必要です。特に、ジェネレータを直接nextに渡すことは避けるべきです。

投稿者 admin

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です