LoginSignup

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

Python fstringのyield_expr

解決したいこと

3.12以降のpythonのfstringの仕様定義の中にあるyield_exprの意味や使い道を教えてください。

fstringの文法定義

pep 701によると以下となっています。

fstring
    | FSTRING_START fstring_middle* FSTRING_END
fstring_middle
    | fstring_replacement_field
    | FSTRING_MIDDLE
fstring_replacement_field
    | '{' (yield_expr | star_expressions) "="? [ "!" NAME ] [ ':' fstring_format_spec* ] '}'
fstring_format_spec:
    | FSTRING_MIDDLE
    | fstring_replacement_field

star_expressionsの定義を調べると、star(*)の付く式も付かない式も合致する定義であろうことが分かりましたので、通常のfstring中の{expr}の部分は、star_expressionsに相当すると思われます。

yield_exprの使い方と使い道については、色々ググっても見つけられていません。識者の方、お教えいただけないでしょうか。

0

1Answer

質問は、以下のどれでしょうか。

  • fstringについて調べていたら、yield_exprという文法定義を見つけたが、それが何者かが分からない
  • yield_exprという文法定義については知っているが、それが明示的にfstringの定義に現れる理由が分からない
  • yield_exprという文法定義については知っているが、それをfstring内で使うケースが思いつかない

上の質問であれば、公式ドキュメントのyield_expressionの説明を参照してください (同じページの使用例も参照)。また「Python Yield式」で検索すれば、別の解説や使用例も見つかります。
中央の質問については、fstringの{}の直下にyieldを括弧無しで書けることを明示するためだと思われます。式内にyieldを書く場合は、(yield 1)のように括弧で囲む必要がありますが、特定の場所(代入文の右辺など)では括弧無しにすることが許されます。
下の質問の場合、私では分からないので、他の方にお願いします。(単純な使用例なら出せますが、意味がある使い方とは言えません)

def test():
    return f'{yield 1}, {yield 2}'

try:
    a = test()
    print(next(a))
    print(a.send('abc'))
    a.send('def')
except StopIteration as s:
    print(s.value)
2Like

Comments

  1. 回答ありがとうございます。私の質問の意図は、1番目のケースでした。

    教えて頂いたページを見たり、試行錯誤して、やっと使い方は分かりました。
    以下のコードは動作します。

    def interactive_template():
        print(f"your name is {yield 'Enter your name:'}")
        yield "How are you?"
    
    gen = interactive_template()
    print(gen.send(input(next(gen))))
    
    • この形式のf文字列はジェネレータとなる関数中でしか使えない。ジェネレータ式中でも使えない。
    • 呼び出し側のnext(gen)に対しては、f文字列のyield_expr中のyieldキーワード以降の値'Enter your name:'が返される
    • 呼び出し側でgen.sendで送った値は、{yield 'Enter your name:'}部分に代入される

    sendメソッドと組み合わせて、インタラクティブにユーザーに質問しながら値を埋めていくテンプレートなどに使えるようです。
    双方向通信的なので、用途が特殊な上、この形式のf文字列を使わなくても実現できそうなので、癖の強い機能と思います。

Your answer might help someone💌