Python の変数がどの範囲でアクセスできるかという「スコープ」に関するルールは、まとめると次の 3 ポイントになるかと思います。
- 関数/クラス/モジュールで区切られる
- 参照の順番は「 LEGB 」
- 宣言はスコープの先頭に巻き上げられる
順に説明していきます。
1. 関数/クラス/モジュールで区切られる
Python には、関数、クラス、モジュールというコードの単位がありますが、それらがスコープの区切り目になります。
具体的には、関数の中と外、クラスの中と外、モジュールの中と外でスコープが異なります。
たとえば、次のコードを見てましょう。
margin = 10 def add_margin(x): margin = 50 return x + margin print add_margin(30) # => 80 print margin # => 10
このコードでは
margin
という名前が add_margin()
という関数の外側と内側に存在しますが、関数の外と中は別の名前空間となるため、これらはまったくの別物です。クラスの場合も同様です。
Const = 3 class MyMath(object): Const = 3.14 print Const # => 3
MyMath
の中の Const
と外の Const
は別物です。モジュールというのは、ここではスクリプトファイルのことを指して言っています。
たとえば、次のような moduleA.py と moduleB.py 、 2 つのファイルがある場合を考えてみましょう。
# moduleA.py greeting = "Hi!"
# moduleB.py greeting = "Ciao!"
次の main.py からそれらを
import
してみます。# main.py import moduleA import moduleB print greeting # => エラー print moduleA.greeting # => Hi! print moduleB.greeting # => Ciao!
すると、
moduleA
、 moduleB
の中のトップレベルに置かれた greeting
という名前はそれぞれ moduleA.greeting
、 moduleB.greeting
でアクセスすることとなります。つまり、モジュール単位で名前空間が区切られます。from moduleA import greeting
というように from ... import ...
を使ってインポートをしてきた場合は名前を衝突させることができますが、基本的には名前空間はモジュール単位で別々になります。つづいて、「2. 参照の順番は「LEGB」」というポイントについて見ていきましょう。
Pythonのスコープ その2
0 件のコメント:
コメントを投稿