web-dev-qa-db-ja.com

ネストされたf文字列

David Beazleyのツイート のおかげで、最近、新しい Python 3.6 f-strings がネストできることを発見しました。

>>> price = 478.23
>>> f"{f'${price:0.2f}':*>20s}"
'*************$478.23'

または:

>>> x = 42
>>> f'''-{f"""*{f"+{f'.{x}.'}+"}*"""}-'''
'-*+.42.+*-'

私はこれが可能であることに驚いていますが、f-stringをネストすることがいつ役立つのか、それがどれほど実用的であるかがわかりません。これはどのようなユースケースをカバーできますか?

注:PEP自体はf-stringのネストについて言及していませんが、 特定のテストケース があります。

43
alecxe

フォーマットされた文字列リテラルがネストを許可するとは思わない(ネストすることにより、f'{f".."}')は、可能なユースケースを慎重に検討した結果です。仕様に準拠するために許可されているだけであると確信しています。

仕様では、 support full Pythonexpressions 括弧内にあると記載されています。フォーマットされた文字列リテラルは、実行時に評価される単なる式です( here および を参照) here )。その結果、別の書式設定された文字列リテラル内の式として書式設定された文字列リテラルを許可するだけで、Python式の完全なサポートを無効にします。

ドキュメントで言及されているユースケースを見つけることができない(そしてテストスイートでのみテストケースを見つける)という事実は、おそらくこれが実装のニース(サイド)効果であり、ユースケースを動機付けているわけではないからです。

私はこれが同じ行でフォーマットパラメータを渡すことだと思うので、f-stringsの使用法を簡素化します。

例えば:

>>> import decimal
>>> width = 10
>>> precision = 4
>>> value = decimal.Decimal("12.34567")
>>> f"result: {value:{width}.{precision}}"
'result:      12.35'

もちろん、プログラマーは絶対に読めないコードを書くことができますが、それは目的ではありません:)

9
Eugene Lisitsky

私は実際に似たようなものに出会っただけで、私は共有したいと思った。

私の特定のケースは、条件付きでいくつかの非常に異なる値を持つ必要がある大きなダーティSQLステートメントですが、いくつかのfstringは同じです(そして他の場所でも使用されます)。

ここに私が意味することの簡単な例を示します。私が選択している列は関係なく同じです(また、他のクエリでも使用されます)が、テーブル名はグループに依存し、ループで実行できるようなものではありません。

毎回mycols=mycolsをstr2に含める必要があるのは、このようなパラメーターが複数ある場合、少し汚い感じがします。

これがうまくいくかどうかはわかりませんが、うまくいきました。 Pythonicがどの程度であるかについては、tbhが本当によくわかりません。

mycols='col_a,col_b'

str1 = "select {mycols} from {mytable} where group='{mygroup}'".format(mycols=mycols,mytable='{mytable}',mygroup='{mygroup}')

group = 'group_b'

if group == 'group_a':
    str2 = str1.format(mytable='tbl1',mygroup=group)
Elif group == 'group_b':
    str2 = str1.format(mytable='a_very_different_table_name',mygroup=group)

print(str2)
5
andrewm4894

ペットプロジェクトに取り組んで、私は自分のDBライブラリを書くことで脇道に追い込まれました。私が発見したことの一つはこれでした:

>>> x = dict(a = 1, b = 2, d = 3)
>>> z = f"""
    UPDATE TABLE 
        bar 
    SET 
        {", ".join([ f'{k} = ?'     for k in x.keys() ])} """.strip()
>>> z
'UPDATE TABLE 
    bar 
SET 
    a = ?, b = ?, d = ?  '

また、これには驚きましたが、正直なところ、本番コードでこのようなことをするかどうかはわかりませんが、本番コードでは他のことはあまりしないと言っています。

2
David