Pythonを学び始めたとき、import
の挙動や from ... import *
の振る舞いなどに戸惑うことがありますよね。
この記事では、**Pythonにおける「シンボル表」と「スコープ」**に注目して、
特に import
によってどのように名前がスコープに登録されるのかをわかりやすく解説します。
シンボル表(symbol table)とは?
Pythonでは、変数や関数、クラスなど「名前」と「中身(オブジェクト)」の対応関係を管理しています。
この管理情報を シンボル表(symbol table) と呼びます。
簡単に言えば、「この名前はどこで何を意味するのか?」を覚えておくメモ帳のようなものです。
スコープとシンボル表の関係
Pythonには「スコープ(有効範囲)」があり、スコープごとに独立したシンボル表が存在します。
-
ローカルスコープ(関数やクラスの中)
- 関数内で定義された変数や引数など
-
グローバルスコープ(モジュール全体)
- ファイル全体で使える関数や変数など
-
組み込みスコープ
-
print()
やlen()
のような標準関数たち
-
モジュールの import とシンボル表への登録
Pythonでモジュールを読み込む方法にはいくつかありますが、それぞれ 現在のシンボル表にどう影響するか を理解しておくことが大切です。
import モジュール名
の場合
import fibo
-
fibo
という モジュール名のみが現在のシンボル表に登録されます -
fibo.py
内で定義された関数や変数は、fibo.fib()
のように モジュールを通してアクセスします
fibo.fib(10) # ✅ OK
fib(10) # ❌ NG: fib は現在のスコープに存在しない
from モジュール名 import *
の場合
from fibo import *
-
fibo.py
内で定義された関数や変数が、現在のシンボル表に直接登録されます -
fib()
のように モジュール名なしでアクセス可能になります - ただし、アンダースコア(_)で始まる名前は登録されません
# fibo.py
def fib(n):
...
def _hidden():
...
# main.py
from fibo import *
fib(10) # ✅ OK
_hidden() # ❌ NG: _hidden は取り込まれていない
import
と from ... import *
の比較表
文法 | シンボル表に登録される名前 | 特徴 |
---|---|---|
import fibo |
fibo のみ |
名前空間が汚れず安全。アクセスは fibo.xxx
|
from fibo import * |
fibo.py の公開名すべて(※_ で始まる名前は除く) |
名前が直接スコープに入る。衝突の危険あり。非推奨 |
補足:name と import の実行タイミング
ここまで「名前がどのようにスコープに入るか」に注目してきましたが、
Pythonでは import
に関する2つの仕様も知っておくとより理解が深まります。
__name__
変数の挙動
Pythonの各モジュールには、特別な変数 __name__
が自動で定義されています。
これは「そのファイルがどのように実行されたか」を示すものです。
実行方法 |
__name__ の値 |
---|---|
モジュールを直接実行 | "__main__" |
他のファイルから import
|
モジュール名(例:"fibo" ) |
# fibo.py
def fib(n):
return n
if __name__ == "__main__":
print(fib(10)) # 直接実行時だけ動作する
モジュールは最初の1回だけ実行される
import fibo
import fibo # 2回目は実行されない(キャッシュ)
- Pythonはモジュールを1度読み込むと、
sys.modules
にキャッシュします - 同じモジュールを再び import しても、再実行はされません
おわりに
- Pythonのシンボル表は、変数や関数などの「名前」と「意味(参照)」の対応を管理する仕組み
- スコープごとにシンボル表が分かれていて、
import
の方法によって登録される名前が変わる -
import モジュール名
ではモジュール名だけが入る -
from モジュール名 import *
では、公開されている名前(※_
から始まるものは除外)が直接入る -
__name__
や「モジュールは一度だけ実行される」という仕様も覚えておくと、理解がより深まる
この記事が、Pythonの名前の仕組みやimportの動作を理解する一助になれば幸いです!