PythonのTrueとFalseは昔、入れ替え可能だった
Hacker Newsで、Pythonの組み込み定数(True・False・None・__debug__など)の「地味な奇妙さ」を扱った記事が話題になった。スレでは「Python 2時代はTrueとFalseを再代入して入れ替えられた」という驚きの仕様が紹介される一方、そこから「Pythonは設計が一貫していない」「Rubyの方が美しかった」といった言語論争にまで発展した。
Pythonの事前に定義された定数って、地味に変じゃないか
出典: sebsite.pw / 元記事はこちら
過去にもこの話題は出てる: https://news.ycombinator.com/item?id=49284392 (自分のコメントつき)、https://news.ycombinator.com/item?id=49250370 。今回また注目されてよかった。
__debug__という定数は結構特殊で、`if __debug__:` で囲んだコードブロックは、PYTHONOPTIMIZE=1を付けるとバイトコードから丸ごと消える。これとassert文だけが、Pythonにおける本物の「条件付きコンパイル」の例だ。__debug__に代入できないのもこのためで、代入できてしまうと`if __debug__:`に対するコンパイラの前提が崩れてしまう。
この定数、正直今まで聞いたことがなかった。Python歴はそこそこ長いつもりなんだけど…まあ使わない知識はガベージコレクトされてるのかもしれない。実際のコードでそんなに使われてるものなの?ちょっとリスキーな気がするんだけど。
0や1みたいな数値リテラルもコンパイル時に畳み込まれるのと同じで、コンパイル時点で__debug__は単純にFalseかTrueになっていて、既存の最適化パスがそのまま処理してるだけ。__debug__に代入してもコンパイラはその変数を実際には読みに行かないから何も起きない。代入自体は他の使い方でおかしなことになるだけ。
Python初期のバージョンにはTrueとFalseが組み込まれてなくて、みんな自分でTrue = 1、False = 0と定義していた、という話を読んだ記憶がある。後からこれが言語に追加された。Python 2ではまだ再代入ができて、True, False = False, Trueと書くと`if False:`が真になるという状態を作れた。Python 3では再代入できなくなっている。
isinstance(True, int)が今でもTrueを返すのは間違いなく事実。
それを覚えてなくて、数年前にバグを踏んだことがある: https://jpscaletti.com/p/8/true-false-one-and-zero
"…"(Ellipsis)も、True・False・Noneと同じで、パース時にハードコードされた値に解決される字句トークンとして振る舞ってるんじゃないの?
「rewolves」? …ああ「resolves」のタイプミスか。Pythonの謎の『ウルフ』要素にすごく興味を持ってしまった。
その通りだけど、Ellipsisは同じ値を持つ、ごく普通の事前定義された定数だよ。
Trueを20年間シャドーイングしても、Pythonはずっと黙って見逃してくれてた。それがある日突然SyntaxErrorになって、自分が書いたチュートリアルが全部壊れる。まさにPythonって感じ。
Pythonはトレンチコートを着た3つのスクリプト言語みたいなものだ。
うわ、なんでこんな挙動になるのか、Pythonの内部実装の詳細を理解したくなってきた:)
昔、自分が気に入っていたPython用の定数ライブラリを作ったことがある。自分のアイデアがいくつか本体に取り込まれてないか気になる: https://github.com/nucypher/constantSorrow/blob/master/tests…
それ、面白いライブラリだね:)
また『Python嫌いの大群』の出番か、という感じ。
個人的な感想だけど、pyは自分が今まで使った中でも指折りにひどい言語・エコシステムだと思う。JSも散々叩かれてきたけど、pyはそれよりさらに数段悪い。あくまで自分の意見なので、怒らないでほしい笑
怒ってはいないけど気になる。自分は何年もPythonを使っていてJSは少し触った程度なんだけど、PythonがJavaScriptより『数段悪い』と感じる具体的な理由を教えてもらえる?
JavaScriptにもいろいろとおかしな部分はあるから、結局どっちを先に学んだ時期に経験したかによる部分も大きいんじゃないかな。あなたはJSを先に触った?
ガラスの家に住んでる人が石を投げてる感じ?それともPythonはバーで書かれた言語だとでも?
確かに。これらは面白い小ネタではあるけど、誰かがそれに引っかかることは実際にはないと思う。
JSの方がPythonよりずっと変な癖が少ないと思う。自分はPythonから入って今も半分くらいPythonを使ってるけど、この記事は一番よくあるやつを見落としてる。__name__ == "__main__"とか、あれ何なんだって話。
『JSの方がPythonよりずっと変な癖が少ない』というなら、ここに挙げられてるようなPythonの変で不快な挙動に匹敵するものをJSで見つけてみてほしい: https://wtfjs.com/
__name__ == "__main__"が、他の言語がインポートされたのか実行ファイルとして起動されたのかを判定する仕組みと比べて、何がそんなに変なの?
PythonがAI関連の仕事で先に使われたというだけの理由で、実質的にスクリプト言語戦争でRubyに『勝った』ことに、今でも納得がいっていない。Rubyには一貫した美しさがある。いくつか例外はあるにせよ、一人の人が一つの核となるアイデアを持って作った言語という感じがする。Pythonはごちゃまぜな印象を受ける。
AIより遥かに前から、非コンピュータ科学者の間で数値データ処理の分野でPythonが人気になっていて、それが直接AIでの利用につながった。理由は明らかで、ソフトウェアエンジニアとしての背景がなくても参入障壁が低かったから。Rubyについてのその感覚には自分も同感。
Pythonの強みはCのライブラリを組み込みやすいところ。だからこそCPythonが事実上唯一のPython実装になっていて、PyPyのような他の実装が普及しなかった。
言語自体には特に不満はないんだけど、`import numpy==1.5.4`と書いて、コードが要求したバージョンをそのまま取得できないのだけは我慢ならない。
比較的最近、スクリプトの中で依存関係のメタデータを定義できるようになっていて、ある程度それができるようになってる。pipスタイルのバージョン指定なら完全一致のものも含めて動く: https://packaging.python.org/en/latest/specifications/inline…
importとパッケージ周りの状況は全体的にひどい。uvが出てくるまで基本的に壊れていたようなもので、しかもuvはまだデフォルトになっていない。ファイルのimportの仕方も変で、ドットで区切られたパッケージがファイル構造に似てるようで微妙に違う。Node.jsならrequire("./foo.js")や"../foo.js"みたいに自明に書ける。新しいJSのimport構文はrequireと地味に違っていて面倒だけど、それでもひどくはない。
他サイトの新着
『データサイエンティストのJupyterノートブックを本番用に直すことが多い』というなら、少なくともR・SAS・MATLABじゃなくてPython/Jupyterでよかったと思うべきだ。
スクリプト言語自体がそもそもひどい。その中でPythonは一番マシな部類。
うわ懐かしい2000年代感。まだ『プログラミング』対『スクリプティング』みたいな区別、本気でやってるの?
自分はPythonの大ファンというわけではないし、フルタイムで使っていてもそう思うことがあるけど、『Pythonはひどい』『データサイエンティストのJupyterノートブックを本番用に直すことが多い』というのは、相関と因果を混同してる気がする。データサイエンティストは、どの言語を使っても良い最適化されたコードは書かないと思う。
まあその通り。Rノートブックを本番に持っていく羽目になることだってあるからね。
Pythonは30年以上前からある言語で、それなりの重い過去を背負っている。まさにその時代の産物という感じ。
だからといって変えられないわけじゃない。PHPを見てみるといい、ここ10年でものすごく進化して、今では多くの部分がちゃんとしてる。
Python 3(000)は、すべてを作り直すチャンスだった。だからある意味、現代のPythonは20年も経っていないとも言える。
『Pythonは初心者に優しい』『理解しやすい』とみんなが言うのが自分には理解できない。自分にとっては、あの独特のクセを全部覚えて追いかけるのがすごく大変。Racket・Scheme・あえて言えばHaskellの方が、学習者にとってはずっとシンプルだと思う。Conal ElliottがType Theory for Allで、Pythonのプログラムを理解する方が遥かに難しいと言っていたのに同感。
Racket/Schemeのサンプルコードが、ことごとく1文字の変数名だけでできてなければ、もっと理解しやすいと思うけどね。
※本記事は5ch(Hacker News)スレッド「Python’s pre-declared constants are kinda weird」より抜粋・要約して構成しています。
この記事のリアクション






まだコメントはありません。