背景
Namespace(名前空間)は、Pythonの基本的な概念の1つで、言語の最初の実装から存在しています。これは、変数、関数、クラスの名前の衝突を避けるために、名前を整理することを目的としています。
問題点
大規模なプロジェクトでは、多くの関数、クラス、変数、およびモジュールが生まれます。適切にnamespaceを使用しないと、重要な名前を上書きしてしまったり、変数の不意のシャドウイングが発生したり、テストや拡張が難しくなります。
解決策
Pythonにおけるnamespaceは、名前とオブジェクトを結びつけるマッピングです。namespaceにはさまざまなレベルがあります:ローカル、グローバル、モジュール空間、クラスです。このような分割を理解することで、必要なオブジェクトに正しくアクセスし、衝突を最小限に抑えることができます。
コードの例:
def foo(): x = 10 # xは関数のローカルnamespace内 print(x) y = 20 # yはモジュールのグローバルnamespace内 foo() print(y)
主な特徴:
同じ関数内でグローバルと同じ名前のローカル変数を宣言したらどうなるか?
ローカルは関数の実行中にグローバルを「隠す」; 関数の外ではグローバルは変わりません。
a = 1 def test(): a = 2 print(a) # 2 test() print(a) # 1
現在の名前空間内のすべての名前のリストを取得するにはどうすればよいか?
関数locals()、globals()、dir()は、現在のスコープ/namespace内の対応するマッピングまたは名前のリストを返します。
クラスの名前空間とインスタンスの違いは何か?
クラスnamespaceは、クラスのすべてのインスタンスで共有される属性を定義します。インスタンスnamespaceは、特定のオブジェクトの属性です。インスタンスの変更はクラスには影響しませんし、その逆もまた然りです。
大規模プロジェクトのすべての部分でfrom mymodule import *を使用しました。その結果、関数名が上書きされ、パッケージ間の名前の衝突によって捕まえにくいバグが発生しました。
利点:
欠点:
インポートのエイリアス(import mymodule as mm)に移行し、モジュールの明確な構造を確立しました。
利点:
欠点: