あらゆる語彙レベルで、インタラクティブなインタプリタプロンプトでの便利な探索を除いfrom amodule import *
て、実際の生活で実際の災害を証明した「当時は良いアイデアのように見えた」設計決定です(それでも、私はあまり暑くありませんその上で-代わりに修飾名を使用するように2つの余分な文字のみを強制します[[接頭辞のみ]]、修飾名は常に裸の名前よりもシャープで柔軟性があります。など!)。import module as m
m.
m
help(m)
reload(m)
この厄介な構造は、コードを読んでいる貧しい人にとって(デバッグを助けるために運命づけられた試みで)、不思議に見える名前がどこから来ているのかを理解するのを非常に難しくします-構造が複数回使用されている場合は不可能です語彙レベル; しかし、一度だけ使用した場合でも、モジュール全体を何度も読み直す必要があります。そうすると、その困惑した裸の名前はモジュールからのものでなければならないことを自分に納得させることができます。
さらに、モジュールの作成者は通常、問題の恐ろしい構造を「サポート」するために必要な極端な問題には行きません。たとえば、コードのどこかにsys.argv
(そしてimport sys
もちろんモジュールの最上部に)を使用している場合、それがモジュールである必要があることをどのように知っていますかsys
...または完全に異なるもの(または非モジュール)... import *
?!これに、使用しているすべての修飾名を掛けると、悲惨さが唯一の最終結果になります。それと、長くて骨の折れるデバッグを必要とする不思議なバグです(通常、Pythonを「取得」する誰かのしぶしぶ助けを借りて...!- )。
関数内で、任意のローカル名を追加およびオーバーライドする方法はさらに悪くなります。基本的ですが重要な最適化として、Pythonコンパイラは関数の本体を調べて、各ベアネームの割り当てまたはその他のバインディングステートメントを探し、割り当てられた名前を「ローカル」と見なします(他の名前はグローバルまたはビルトインである必要があります)。(名前空間として使用する明示的なdictがない場合import *
と同様にexec somestring
)突然、名前がローカルで、名前がグローバルであることが完全に謎になります。そのため、貧弱なコンパイラは、名前検索ごとに可能な限り遅い戦略に頼らなければなりません。 、ローカル変数にdictを使用し(通常使用するコンパクトな「ベクトル」の代わりに)、参照されるベアネームごとに最大3つのdictルックアップを繰り返し実行します。
Pythonインタラクティブプロンプトに移動します。タイプimport this
。何が見えますか?Pythonの禅。そのテキストの最後の、そしておそらく最大の知恵は何ですか...?
名前空間は素晴らしいアイデアの1つです。もっと多くのことをしましょう!
修飾名が非常に望ましい場合にベアネームの使用を強制することにより、基本的にこの賢明な推奨事項とは正反対のことを行います。名前空間の素晴らしさとホンキングチュードを賞賛する代わりに、それらの多くを行うのではなく、 2つを完全に分解します。すぐに使用できる優れた名前空間(インポートするモジュールの名前空間と、インポートする字句スコープの名前空間)を使用して、単一の、不潔で、バグが多く、遅く、堅固で、使用できない混乱を引き起こします。
Pythonで初期の設計上の決定を1つ変更できれば(これは難しい選択です。def
特にlambda
、Javascriptを使用すると、非常に読みやすいように呼び出されるので、すぐに呼び出されます;-)、 Guidoのアイデアfunction
をさかのぼって一掃します。import *
マインド。インタラクティブなプロンプトで探索するのに便利だと言われている量は、それが引き起こした悪の量のバランスをとることができません...!- )