このコードスニペットを検討してください。
global open
print(open)
これにより、次の結果が得られます。
<built-in function open>
私の質問は次のとおりです。名前をいオープンこの例では、内蔵またはグローバルスコープに属し?
グローバル宣言により、名前openがグローバルスコープにマップされるように強制される(したがって、エラーが発生する)と思いましたが、ここでは発生していません。どうして?
まず、直接の答え:
名前open
は最上位の名前空間に属しています。これは本質的に「グローバルで検索し、ビルトインにフォールバックし、グローバルに割り当てる」ことを意味します。
追加するglobal open
だけで、それがすでに存在していた最上位の名前空間に属するように強制されます。(これは、関数やクラス内ではなく、最上位のコードであると想定しています。)
それはあなたが読んだものを縮小しているように見えますか?まあ、それはもう少し複雑です。
リファレンスドキュメントによると:
この
global
ステートメントは、現在のコードブロック全体を保持する宣言です。これは、リストされた識別子がグローバルとして解釈されることを意味します。
ただし、ドキュメントの他の部分が示唆しているように見えますが、「グローバルとして解釈される」とは、実際には「グローバル名前空間で検索される」という意味ではなく、「名前の解決」に記載されている「トップレベルの名前空間で検索される」という意味です。
名前は、グローバル名前空間、つまりコードブロックを含むモジュールの名前空間と、組み込みの名前空間であるモジュールの名前空間を検索することにより、最上位の名前空間で解決されます
builtins
。グローバル名前空間が最初に検索されます。名前がそこに見つからない場合は、builtins
名前空間が検索されます。
また、「グローバルとして」とは、「グローバル名前空間内の名前が検索されるのと同じ方法」、別名「トップレベルの名前空間内」を意味します。
そしてもちろん、トップレベルの名前空間への割り当ては、ビルトインではなく、常にグローバルに行われます。(そのため、そもそもビルトインopen
をグローバルopen
でシャドウイングできます。)
また、exec
とeval
ドキュメントで説明されているように、これでさえ、実行されたコードにはまったく当てはまらないことに注意してexec
ください。
グローバルディクショナリにキーの値が含まれていない場合、
__builtins__
組み込みモジュールのディクショナリへの参照がbuiltins
そのキーの下に挿入されます。そうすれば、__builtins__
に渡す前に独自の辞書をグローバルに挿入することで、実行されたコードで使用できるビルトインを制御できますexec()
。
そしてexec
、最終的には、モジュールとスクリプトがどのように実行されるかです。
したがって、実際に発生するのは、少なくともデフォルトでは、グローバル名前空間が検索されることです。名前が見つからない場合は、グローバル名前空間で__builtins__
値が検索されます。それがモジュールまたはマッピングの場合は、検索されます。
特にCPythonでこれがどのように機能するのか知りたい場合は、次のようにします。
global
ステートメントが機能します。名前を別の名前ではなく、グローバルシンボルテーブルに強制的に追加します。LOAD_GLOBAL
し、グローバル用の命令を発行します。(またco_names
、グローバル変数やco_cellvars
セル変数など、コードオブジェクトのタプルメンバーにさまざまな名前を格納します。)__globals__
れると、属性としてアタッチされます。__globals__
なりf_globals
フレームのために。LOAD_GLOBAL
期待することを正確に実行することによって各命令を処理します。f_globals
__builtins__
exec
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加