2 ポイント 投稿者 GN⁺ 2025-07-20 | 1件のコメント | WhatsAppで共有
  • fstrings.wtfは、Pythonのf-string機能への理解度を確認するためのオンラインクイズ
  • 最新のPython 3.13バージョンで適用されるf-stringのさまざまな動作と例外事項をテストする問題で構成されている
  • ユーザーは別途の手順なしですぐにクイズを開始できる
  • 実務でよく遭遇するf-string関連のトリックや誤動作をあらかじめ体験してみることができる

1件のコメント

 
GN⁺ 2025-07-20
Hacker Newsのコメント
  • 文字列補間機能は型推論のようなもので、いったん慣れると無い状態がとても不便に感じられる。少しずつ機能が増えるほど便利になるように思えるが、ある時点で読みにくいコードになってしまうことに気づく。一般にCSの分野ではどんな機能でももっと盛り込みたくなりがちだが、数学的にそれが難しい場合もある。ここでは、まったく無い状態と多すぎる状態の両方を避ける必要がある。PythonとC#はユーザーの好みに任せる方式を選んだ。16ページ分の複雑な補間文字列も書けるが、同僚には嫌がられるかもしれないし、コードレビューで却下されるかもしれない。C++ 23は最初から補間を禁じるスタイルだ。Rustは識別子だけ補間を許可する非常に限定的な選択肢を採用しており、これを物足りないと感じる人もいれば、過剰だと感じる人もいる

    • Java String Templateチームも似たような過程をたどったのだと思う。見た目にはかなり洗練されたシステムだったが、実際に使おうとすると方向性に無理があると感じ、結局まるごと取り下げた。補間機能への需要と、ここまで投じた労力を考えると、かなり興味深い決定だ。最終的に後戻りできないと判断し、原点に戻ったわけだ

    • 純粋性と実用性は相反し、各言語はそれぞれ異なるバランス点を見つけることになる。決まった正解がないので、開発者ごとに自分なりの正しさを繰り返し主張することになる

    • C#で数値や日付のフォーマットが必要になるたびに、まずドキュメントを調べることになる。あのミニ言語があまりにひどいので、わざわざ覚えないことにしている

    • 複雑な例に合わせずに補間を適切にコントロールするのは難しくなかった。f-stringの中にf-stringを入れ子にして使う必要性は感じたことがなく、よく使うフォーマット指定子も :02x くらいだ

    • Rustの限定的な補間方式が解決策だとはまったく思わない。特定の状況でしか動かないので、コードのリファクタリング時に常に気を配る必要があり、不要な手直しが増える。少なくともフィールドアクセス程度は許可すべきだと思う。一方、Pythonでは例のような変なケースがあるにせよ、実際の利用者は気にせず普通にf-stringを快適に使っている

  • fstring.help などで説明されているいくつかのテクニック(中央揃え、0x/0b/0oプレフィックス、ASCII表示など)を最近知った。入れ子のf-stringの問題にも関心があったが、3.11までは引用符を変えるだけで可能だった。3.12でいくつもの制約が整理されたと理解している。f-stringのおかげで便利ではあるが、旧式の % フォーマット、.format() 方式、新しい方式の微妙な違いまで頻繁に使い分けなければならないのは思った以上に面倒で、避けられない場面も多い。使い勝手は向上したが、いまだに古い方式を使わざるを得ないときのもどかしさは大きい

    • 3.12でこのあたりが整理されたことは公式ドキュメントで確認できる

    • ときどき同僚やAIがlogger呼び出しでf-stringを使っているのを見るが、loggerは遅延補間のためにわざわざそう実装されているはずなのに、その便利な機能をわざわざ捨ててしまうのが不思議だ

    • 入れ子のf-stringはトリック問題のようなものだと思う。同じスタイルの引用符で入れ子にできる機能が追加されることは知っていたが、どのバージョンかは知らなかった。今でも f'{f"{}"}' のトリックを使っているが、その理由は自分のコードを少し古いPythonバージョンまでサポートしたいからだ

  • f-stringで等号記号(=)を使って式と値を一緒に出力する機能を初めて知った

    • Pythonのリリースノートは本当に読む価値があると思う。いつも良い意味で驚かされる。等号機能はPython 3.8で追加された 関連リンク

    • 関数のキーワード引数でも似た機能のPEPが採用されなかったのは残念だ。foo(bar=bar) の代わりに foo(bar=) の形になっていれば、単に引数を渡している場合との違いももっと見えやすくなり、デバッグにも効率的だったはずだ

    • 驚きはあるが、それに見合うほどの価値を提供していない機能だと思う。予想外の挙動をしやすく、バグの温床になりかねないのが心配だ。locals() の一部だけを出力する標準関数のほうがよい気がする

    • デバッグ出力では非常によく使うパターンだ。C++では、一方の式を引用符付きで、もう一方をそのまま書く癖がついた。分かりやすくなって、あまり考えなくてよいのがいい

    • print(f) でデバッグするときに本当に便利だ

  • URLとは違って、実際にはWTF級の質問はほとんど無いと思う。20番や21番の質問のように、本当に驚くものがいくつかある程度だ

    • 自分はwalrus operatorがあまりにも便利なので、絶対に手放せない。パターンマッチングや多分岐処理のときにコードがずっときれいになる。頻繁に使うわけではないが、ぴったりハマる場面では効果が大きい

    • これはwalrus operatorのせいではなく、Pythonの string.format の動作方式によるものだ 関連ドキュメント を参照

  • f-stringが導入される前後以降、Pythonを本格的に使ったことはないが、文法ルールはほとんど当てられたし、むしろ戻り値まわりのミスを何度かしたくらいだった。f-string自体はPythonでいちばんWTF度の低い部分なのではないかと思う

  • Lua向けのf-string風ライブラリを作りながらかなり多くの構文を学んだが、f"{...}" と walrus operator は予想していなかった。それでも Wat 級の奇妙さとは程遠い。関連ライブラリは こちら を参照

    • そのライブラリは本当にすごく良さそうだ
  • 特にWTFと言うほどの内容はないと思う。かなりの部分はf-stringというより str.format() ミニ言語の文法に関する話だ

    • WTFと言いたくなる点はいくつかあったが、ほとんどは文字列フォーマット構文を知っているかどうかの話だ
  • 機能が多すぎて閾値を超えているように思う。ひとりの開発者がすべてを把握する必要もないし、実際に使うたびにドキュメントを調べることになるので非効率だ。たまにしか使わないので文法を忘れるし、同じ機能を自分で実装したほうがずっと速く、同僚が見てもカスタマイズしやすいという利点がある。左パディング? 2行の関数で十分だ。フォーマット文法(nが先か < が先かなど)で迷うくらいなら、その場しのぎで自分で実装したほうが早い

    • 左パディングのようなものは string.format メソッドでも使え、その方式はPython 2.6(2008年リリース)から存在していた 関連ドキュメント を参照。自分はむしろフォーマット文法が頭に残りやすく、便利に使っている。しかもフォーマットはカスタマイズ用のフックが用意されている

    • 自分は中間的な落としどころを選びたい。pad_left/pad_right 関数にパディング文字もキーワード引数で直接指定できるのがいちばん快適だ。日常的にそこそこ必要になるので、標準ライブラリにあるとよい。言語ライブラリにこういうものがないと、後で各プロジェクトごとに質の低い実装が乱立して、JavaScriptのようになってしまう。自分のプロジェクトでは ^ や <> のようなPythonのフォーマットまで使うことはないだろうが、等幅フォントでの出力が重要なソフトウェアでは、むしろ非常に重要な機能になりうる

    • 変な機能や裏技めいたものを、ひとつのコードベースの中で繰り返し多用することはある。いったん作ってコピペし、そのまま再利用し続けることが多い

  • もしこういう構文がJavaScriptだったら、ほとんどは直感的でない文法や変な機能だと嘆かれていただろう

    • 自分の考えでは、このクイズの本当の論点は、JavaScriptに劣らずPythonにもfootgunが多いということなのだと思う。JSではこういう「WTF」系の投稿がよくあるからだろう

    • 細かなトリックを除いても、JavaScriptのほうが圧倒的に直感的でない文法の王様だと思う。Pythonのf-string要素も独特ではあるが、露出するのは特定の状況だけだし、JSでは配列2つを比較する前に依存関係のインストール待ちをしていることすらある

    • JavaScriptのテンプレートリテラルについて聞きたい。Pythonのように let template = 'hello ${name}'; として、template.format({ name: 'joe' }) のように何度も動的に値を埋めることはJSではできないように思える。だから自分で実装するしかなかった。タグ付きテンプレートなども見たが、テンプレート自体を再利用するのは難しかった。JSの文法や変な機能を嘆く気持ちには大いに共感する

    • もしPerlだったら、むしろ称賛の声が集まっていただろう

  • pyformat.info(リンク)を参考にしている。極端に詳細というわけではないが、たいていの妥当な例はひと通りまとまっている