Pythonの用語を繰り返し唱えることにより、身につくかもっていう取り組みです。
from
used to show where somebody/something starts
https://www.oxfordlearnersdictionaries.com/definition/english/from?q=from
ChatGPT
pythonで from が機能する仕組みのソースコードを教えてください
なるほど。あなたは Python の from ... import ... 文が内部でどのように動作しているのか、その仕組みを「ソースコードレベルで」知りたいのですね。順を追って解説します。
- 基本の理解
Python の from module import name は内部的には以下の処理を行います:
指定されたモジュールを ロード する
モジュール内のオブジェクト(関数・クラス・変数など)を取得する
現在の名前空間にそのオブジェクトを登録する
例:
from math import sqrt
は、ほぼ次のような処理です(擬似コード):
import math # モジュールをロード
sqrt = math.sqrt # 名前空間に追加 - CPython での実際の実装
Python の from ... import ... 文は コンパイル時に IMPORT_NAME と IMPORT_FROM バイトコードに変換されます。
バイトコード例
from math import sqrt
$ python -m dis
1 0 LOAD_CONST 0 (0)
2 LOAD_CONST 1 (('sqrt',))
4 IMPORT_NAME 0 (math)
6 IMPORT_FROM 1 (sqrt)
8 STORE_NAME 0 (sqrt)
10 POP_TOP
12 LOAD_CONST 2 (None)
14 RETURN_VALUE
IMPORT_NAME → モジュール math をロード
IMPORT_FROM → モジュールから指定された名前 sqrt を取得
STORE_NAME → 現在の名前空間に格納 - CPython 内部ソースコード
CPython のソースでは import 文は以下のように処理されています。
Python/ceval.c 内のバイトコード実行
case TARGET(IMPORT_NAME): {
PyObject *name = GETITEM(names, oparg);
PyObject *fromlist = POP(); // 例: ('sqrt',)
PyObject *level = POP(); // 相対インポート用
PyObject *module = import_name(name, fromlist, level);
PUSH(module);
DISPATCH();
}
import_name() が実際にモジュールをロード
その後 IMPORT_FROM で指定された名前を取り出す
Python/import.c の import_name 関数
PyObject *
PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
PyObject *locals, PyObject *fromlist,
int level)
{
PyObject module;
/ モジュールを sys.modules から取得、なければロード /
module = _PyImport_FindAndLoad(name, level);
if (fromlist != NULL && PyTuple_Size(fromlist) > 0) {
/ fromlist にある名前をモジュールから取得 */
for (i = 0; i < PyTuple_Size(fromlist); i++) {
PyObject attr = PyObject_GetAttr(module, PyTuple_GetItem(fromlist, i));
/ エラー処理省略 */
}
}
return module;
}
ポイント:
fromlist が空なら単純に import module
fromlist がある場合はモジュールから属性を取得 (IMPORT_FROM 相当)
モジュールは sys.modules キャッシュを使う - Python レベルで擬似的に書くと
import sys
import importlib
def from_import(module_name, names):
# モジュールを取得またはロード
if module_name in sys.modules:
module = sys.modules[module_name]
else:
module = importlib.import_module(module_name)
# 名前空間に追加
globals_ = globals()
for name in names:
globals_[name] = getattr(module, name)
from_import('math', ['sqrt', 'pi'])
print(sqrt(16))
print(pi)
このコードは from math import sqrt, pi と同等です。
💡 まとめ
from ... import ... は内部的には IMPORT_NAME → IMPORT_FROM → STORE_NAME というバイトコード列で実装
実際のロードは PyImport_ImportModuleLevelObject など C コードで行われる
Python レベルでも importlib + getattr でほぼ同じ処理を再現可能
もし希望なら、私は PlantUML で「from import の処理フロー図」 を描いて、sys.modules キャッシュからロード → 属性取得 → 名前空間格納までを視覚化することもできます。
作りますか?
はい。
了解です!では from ... import ... の動作フローを PlantUML で図示します。以下はモジュールロードから名前空間登録までの流れです。
@startuml
title Python from ... import ... 処理フロー
start
:from module import name 実行;
:モジュール名(module)を取得;
if (sys.modulesにmoduleはある?) then (はい)
:キャッシュされたモジュールを取得;
else (いいえ)
:モジュールを importlib でロード;
:sys.modules に登録;
endif
:fromlist 内の名前(name)を1つずつ取得;
:モジュールから getattr で属性を取得;
:現在の名前空間(globals)に name を登録;
stop
@enduml
💡 フロー解説
モジュール取得
まず sys.modules に存在するか確認
なければロードしてキャッシュに登録
名前取得
fromlist にある名前を getattr(module, name) で取り出す
名前空間登録
現在のスコープに name = module.name として登録
希望なら次に、この PlantUML を 実際の Python C 実装 (PyImport_ImportModuleLevelObject) に沿った詳細版 に拡張して、IMPORT_NAME → IMPORT_FROM → STORE_NAME のバイトコードの流れまで入れた図も作れます。
作りますか?
はい。
では、先ほどのフローをさらに CPython の バイトコードレベル に沿って詳細化した PlantUML 図を作ります。from ... import ... が内部でどのように IMPORT_NAME → IMPORT_FROM → STORE_NAME と処理されるかを含めています。
@startuml
title Python from ... import ... 処理フロー(CPython バイトコード詳細版)
start
:from module import name 実行;
:コンパイル時にバイトコードに変換;
note right
IMPORT_NAME → モジュールをロード
IMPORT_FROM → モジュールから属性取得
STORE_NAME → 名前空間に登録
end note
:IMPORT_NAME 実行;
if (sys.modulesにmoduleはある?) then (はい)
:キャッシュされたモジュールを取得;
else (いいえ)
:モジュールを importlib / C API でロード;
:sys.modules に登録;
endif
:IMPORT_FROM 実行;
:モジュールから getattr(module, name) で属性を取得;
:STORE_NAME 実行;
:現在の名前空間(globals)に name を登録;
stop
@enduml
🔍 フロー解説
バイトコード生成
from math import sqrt はコンパイルされると
IMPORT_NAME math
IMPORT_FROM sqrt
STORE_NAME sqrt
という命令列に変換される
IMPORT_NAME
モジュールが sys.modules にあるか確認
なければロードしキャッシュに登録
IMPORT_FROM
モジュールオブジェクトから指定された名前を getattr で取得
STORE_NAME
現在のスコープ(グローバル/ローカル)に名前を登録
もし希望なら、次のステップとして 相対インポートや from module import * まで含めたさらに完全なフロー も PlantUML で描けます。
描きますか?
はい。
では、相対インポートや from module import * まで含めた 完全版フロー を PlantUML で作成します。CPython の内部処理(IMPORT_NAME → IMPORT_FROM → STORE_NAME / getattr / all 処理)まで含めています。
@startuml
title Python from ... import ... 完全フロー(相対・*対応)
start
:from module import name(s) 実行;
:コンパイル時にバイトコードに変換;
note right
IMPORT_NAME → モジュールをロード
IMPORT_FROM → モジュールから属性取得
STORE_NAME → 名前空間に登録
end note
:IMPORT_NAME 実行;
if (相対インポートか?) then (はい)
:現在のパッケージから相対パスを解決;
endif
if (sys.modulesにmoduleはある?) then (はい)
:キャッシュされたモジュールを取得;
else (いいえ)
:モジュールを importlib / C API でロード;
:sys.modules に登録;
endif
if (fromlist が '*' か?) then (はい)
:モジュールの all を取得;
:all 内の名前をループ;
else (いいえ)
:fromlist 内の指定された名前をループ;
endif
:各名前を IMPORT_FROM で取得;
note right
getattr(module, name) 相当
end note
:STORE_NAME 実行;
:現在の名前空間(globals/local)に name を登録;
stop
@enduml
🔍 詳細解説
相対インポート
from .submodule import foo の場合、現在のパッケージの位置から相対パスを解決
キャッシュチェック
sys.modules に存在すれば再ロード不要
存在しなければ importlib や C API でロードしキャッシュ登録
- インポート
from module import * の場合、モジュールの all を参照して名前を取得
all がなければ _ で始まる名前は除外して全属性取得
属性取得
getattr(module, name) によって指定された名前を取得
名前空間登録
STORE_NAME バイトコードに対応
グローバル・ローカルのスコープに登録される
もし希望なら、この PlantUML をさらに CPython の C ソースコード関数 (PyImport_ImportModuleLevelObject / import_name / import_from) と対応させたコメント入り図 に進化させることもできます。
作りますか?
はい。
了解です。では、先ほどの完全フローをさらに CPython の C ソースコード関数に対応させたバージョン に拡張します。各ステップに 実際の関数名や処理箇所 を注記しました。
@startuml
title Python from ... import ... 処理フロー(CPython C ソース対応版)
start
:from module import name(s) 実行;
:コンパイル時にバイトコードに変換;
note right
IMPORT_NAME → モジュールをロード
IMPORT_FROM → モジュールから属性取得
STORE_NAME → 名前空間に登録
end note
:IMPORT_NAME 実行;
if (相対インポートか?) then (はい)
:現在のパッケージから相対パスを解決;
note right: Python/import.c\nresolve_name_in_package()
endif
if (sys.modulesにmoduleはある?) then (はい)
:キャッシュされたモジュールを取得;
note right: sys.modules 参照
else (いいえ)
:モジュールを importlib / C API でロード;
note right: PyImport_ImportModuleLevelObject()
:sys.modules に登録;
endif
if (fromlist が '*' か?) then (はい)
:モジュールの all を取得;
note right: _PyImport_GetModuleAttrString(module, "all")
:all 内の名前をループ;
else (いいえ)
:fromlist 内の指定された名前をループ;
endif
:各名前を IMPORT_FROM で取得;
note right
PyObject_GetAttr(module, name) 相当
エラー発生時は ImportError
end note
:STORE_NAME 実行;
:現在の名前空間(globals/local)に name を登録;
stop
@enduml
🔍 コメント付きポイント
相対インポート
C ソース関数 resolve_name_in_package() でパッケージ基準のモジュール名を計算
モジュールロード
PyImport_ImportModuleLevelObject() がメイン関数
sys.modules にキャッシュされた場合はロード不要
- インポート
_PyImport_GetModuleAttrString(module, "all") を使用
ない場合は _ で始まる名前を除いた全属性取得
属性取得
PyObject_GetAttr(module, name) によって各名前を取得
存在しなければ ImportError 発生
名前空間登録
STORE_NAME バイトコードでグローバル/ローカルに登録
💡 この図を読むと、
Python レベルの from ... import ...
バイトコードレベル (IMPORT_NAME, IMPORT_FROM, STORE_NAME)
C 実装レベル (PyImport_ImportModuleLevelObject, PyObject_GetAttr)
までの処理が一目で追えます。
希望であれば、さらに *「相対インポート + インポート + 名前衝突処理」まで含めた最終完全版フロー にして、ImportError 発生時の分岐まで含めた図も作れます。
作りますか?
はい。
了解です。それでは、相対インポート・* インポート・名前衝突・ImportError 発生時の分岐まで含めた最終完全版フロー を PlantUML で作成します。CPython の関数呼び出しも注記しています。
@startuml
title Python from ... import ... 最終完全版フロー(CPython対応)
start
:from module import name(s) 実行;
:コンパイル時にバイトコードに変換;
note right
IMPORT_NAME → モジュールをロード
IMPORT_FROM → モジュールから属性取得
STORE_NAME → 名前空間に登録
end note
:IMPORT_NAME 実行;
if (相対インポートか?) then (はい)
:現在のパッケージから相対パスを解決;
note right: Python/import.c\nresolve_name_in_package()
endif
if (sys.modulesにmoduleはある?) then (はい)
:キャッシュされたモジュールを取得;
note right: sys.modules 参照
else (いいえ)
:モジュールを importlib / C API でロード;
note right: PyImport_ImportModuleLevelObject()
:sys.modules に登録;
endif
if (fromlist が '*' か?) then (はい)
:モジュールの all を取得;
note right: _PyImport_GetModuleAttrString(module, "all")
:all 内の名前をループ;
else (いいえ)
:fromlist 内の指定された名前をループ;
endif
:各名前を IMPORT_FROM で取得;
note right
PyObject_GetAttr(module, name) 相当
end note
if (名前が取得できた?) then (はい)
if (名前が既に名前空間に存在?) then (はい)
:上書き警告 / Pythonは上書き可能;
else (いいえ)
:名前空間に登録;
endif
else (いいえ)
:ImportError 発生;
stop
endif
:STORE_NAME 実行;
:現在の名前空間(globals/local)に name を登録;
stop
@enduml
🔍 フロー詳細
相対インポート
resolve_name_in_package() で現在のパッケージ基準に変換
モジュールキャッシュ
sys.modules に存在すれば再ロード不要
なければ PyImport_ImportModuleLevelObject() でロードしキャッシュ
- インポート
_PyImport_GetModuleAttrString(module, "all") で取得
all がなければ _ で始まる名前を除いた全属性
属性取得
PyObject_GetAttr(module, name) で取得
取得できなければ ImportError
名前衝突
名前空間に既存の名前があっても上書き可能
Python は警告なしに上書き
最終登録
STORE_NAME でグローバル/ローカル名前空間に登録
💡 この図で、
通常インポート
相対インポート - インポート
名前衝突
ImportError 分岐
まで完全に追えるフローになっています。
必要であれば、次に 実際の C ソースコードの関数呼び出し関係図 として UML シーケンス図にして、呼び出し順序まで可視化することも可能です。
作りますか?
はい。
了解です。では、from ... import ... の C ソースコード関数呼び出し順序 を UML シーケンス図で可視化します。CPython の内部関数 (PyImport_ImportModuleLevelObject → _PyImport_FindAndLoad → PyObject_GetAttr) まで追えます。
@startuml
title Python from ... import ... 関数呼び出しシーケンス図(CPython対応)
actor PythonCode as "ユーザコード"
participant "バイトコード実行器\n(PyEval_EvalFrameEx)" as Eval
participant "IMPORT_NAME / IMPORT_FROM" as ImportInstr
participant "PyImport_ImportModuleLevelObject()" as ImportModule
participant "_PyImport_FindAndLoad()" as FindAndLoad
participant "モジュールオブジェクト" as ModuleObj
participant "PyObject_GetAttr()" as GetAttr
participant "名前空間(globals/local)" as Namespace
PythonCode -> Eval : from module import name(s)
Eval -> ImportInstr : IMPORT_NAME
ImportInstr -> ImportModule : PyImport_ImportModuleLevelObject(module, fromlist)
ImportModule -> FindAndLoad : _PyImport_FindAndLoad(module)
FindAndLoad -> ModuleObj : モジュールロードまたは sys.modules 参照
ModuleObj --> FindAndLoad : モジュールオブジェクト返却
FindAndLoad --> ImportModule : モジュール返却
alt fromlistが存在
ImportInstr -> GetAttr : getattr(module, name)
GetAttr --> ImportInstr : オブジェクト返却 / ImportError発生
end
ImportInstr -> Namespace : STORE_NAMEで名前空間に登録
note right of Namespace
名前空間に既存の名前があれば上書き
ImportError発生時は例外処理
end note
@enduml
🔍 説明
ユーザコード が from module import name を実行
Eval(バイトコード実行器) がバイトコード IMPORT_NAME → IMPORT_FROM を解釈
IMPORT_NAME
PyImport_ImportModuleLevelObject() 呼び出し
内部で _PyImport_FindAndLoad() を使い、モジュールをロード or キャッシュ取得
IMPORT_FROM
PyObject_GetAttr(module, name) で指定名前を取得
失敗時は ImportError 発生
STORE_NAME
名前空間に登録
既存名は上書き可能
💡 このシーケンス図で、Python レベル → バイトコード → C API → 名前空間登録までの流れを順序付きで追えます。
希望であれば、さらに 相対インポート・* インポート・all 処理も含めた完全版シーケンス図 に拡張できます。
作りますか?
はい。
了解です。それでは、相対インポート・* インポート・all 処理・ImportError 分岐も含めた完全版シーケンス図 を作成します。CPython の関数呼び出し順序と分岐まで可視化しています。
@startuml
title Python from ... import ... 完全シーケンス図(相対・*対応・CPython関数)
actor PythonCode as "ユーザコード"
participant "バイトコード実行器\n(PyEval_EvalFrameEx)" as Eval
participant "IMPORT_NAME / IMPORT_FROM" as ImportInstr
participant "PyImport_ImportModuleLevelObject()" as ImportModule
participant "_PyImport_FindAndLoad()" as FindAndLoad
participant "resolve_name_in_package()" as ResolveRel
participant "モジュールオブジェクト" as ModuleObj
participant "_PyImport_GetModuleAttrString('all')" as GetAll
participant "PyObject_GetAttr()" as GetAttr
participant "名前空間(globals/local)" as Namespace
PythonCode -> Eval : from module import name(s)
Eval -> ImportInstr : バイトコード解釈
ImportInstr -> ResolveRel : 相対インポートの場合
ResolveRel --> ImportInstr : モジュール名解決
ImportInstr -> ImportModule : PyImport_ImportModuleLevelObject(module, fromlist)
ImportModule -> FindAndLoad : _PyImport_FindAndLoad(module)
FindAndLoad -> ModuleObj : sys.modules または 新規ロード
ModuleObj --> FindAndLoad : モジュールオブジェクト
FindAndLoad --> ImportModule : モジュール返却
alt fromlist が '*'
ImportInstr -> GetAll : all 属性取得
GetAll --> ImportInstr : 名前リスト
loop 各名前
ImportInstr -> GetAttr : getattr(module, name)
GetAttr --> ImportInstr : オブジェクト / ImportError
ImportInstr -> Namespace : STORE_NAME登録
end
else 指定名リストの場合
loop 各名前
ImportInstr -> GetAttr : getattr(module, name)
GetAttr --> ImportInstr : オブジェクト / ImportError
ImportInstr -> Namespace : STORE_NAME登録
end
end
note right of Namespace
名前空間に既存の名前があれば上書き
ImportError発生時は例外処理
end note
@enduml
🔍 説明
相対インポート
resolve_name_in_package() でパッケージ基準にモジュール名を解決
モジュール取得
_PyImport_FindAndLoad() で sys.modules 参照
キャッシュがなければロード
- インポート
_PyImport_GetModuleAttrString('all') で名前リスト取得
ループで getattr → STORE_NAME で登録
指定名リスト
ループで getattr → STORE_NAME で登録
名前衝突
既存の名前は上書き可能
ImportError 分岐
getattr に失敗すると例外発生
💡 この図で、Python レベル → バイトコード → C API → モジュールロード → 名前空間登録まで ほぼ全ての内部処理 を順序付きで追えます。
希望であれば、この図をさらに sys.modules キャッシュとロードフローを分岐付きで詳細化した図 に拡張することも可能です。
作りますか?
はい。
了解です。それでは、sys.modules キャッシュチェックとロード分岐まで含めた最終完全版シーケンス図 を作成します。これで from ... import ... の処理フローを Python レベルからバイトコード、C API、モジュールキャッシュ、属性取得、名前空間登録まで網羅できます。
@startuml
title Python from ... import ... 最終完全シーケンス図(sys.modulesキャッシュ対応)
actor PythonCode as "ユーザコード"
participant "バイトコード実行器\n(PyEval_EvalFrameEx)" as Eval
participant "IMPORT_NAME / IMPORT_FROM" as ImportInstr
participant "PyImport_ImportModuleLevelObject()" as ImportModule
participant "_PyImport_FindAndLoad()" as FindAndLoad
participant "resolve_name_in_package()" as ResolveRel
participant "sys.modules" as SysModules
participant "モジュールオブジェクト" as ModuleObj
participant "_PyImport_GetModuleAttrString('all')" as GetAll
participant "PyObject_GetAttr()" as GetAttr
participant "名前空間(globals/local)" as Namespace
PythonCode -> Eval : from module import name(s)
Eval -> ImportInstr : バイトコード解釈
ImportInstr -> ResolveRel : 相対インポートの場合
ResolveRel --> ImportInstr : モジュール名解決
ImportInstr -> SysModules : sys.modulesにmoduleがあるか?
alt キャッシュあり
SysModules --> ImportInstr : モジュールオブジェクト返却
else キャッシュなし
ImportInstr -> ImportModule : PyImport_ImportModuleLevelObject(module, fromlist)
ImportModule -> FindAndLoad : _PyImport_FindAndLoad(module)
FindAndLoad -> ModuleObj : 新規ロード
ModuleObj --> FindAndLoad : モジュールオブジェクト返却
FindAndLoad --> ImportModule : モジュール返却
ImportModule --> ImportInstr : モジュールオブジェクト
ImportInstr -> SysModules : sys.modulesに登録
end
alt fromlist が '*'
ImportInstr -> GetAll : all 属性取得
GetAll --> ImportInstr : 名前リスト
loop 各名前
ImportInstr -> GetAttr : getattr(module, name)
GetAttr --> ImportInstr : オブジェクト / ImportError
ImportInstr -> Namespace : STORE_NAME登録
end
else 指定名リストの場合
loop 各名前
ImportInstr -> GetAttr : getattr(module, name)
GetAttr --> ImportInstr : オブジェクト / ImportError
ImportInstr -> Namespace : STORE_NAME登録
end
end
note right of Namespace
名前空間に既存の名前があれば上書き
ImportError発生時は例外処理
end note
@enduml
🔍 最終版の特徴
相対インポート
resolve_name_in_package() でパッケージ基準のモジュール名を解決
sys.modules キャッシュチェック
キャッシュあり → そのまま取得
キャッシュなし → _PyImport_FindAndLoad() でロード → sys.modules に登録
fromlist / '*' 対応
- インポート → all 参照
指定名リスト → 名前ごとに getattr で取得
属性取得
PyObject_GetAttr() によるオブジェクト取得
取得失敗 → ImportError
名前空間登録
STORE_NAME で globals/local に登録
既存名は上書き可能
💡 この図で、Python レベルの from ... import ... が キャッシュチェック、相対インポート、* インポート、ImportError、名前空間登録まで どのように内部で動作するか完全に追えます。
必要であれば、さらに 例外処理フロー(ImportError発生時の traceback 生成や例外伝播) まで含めたシーケンス図に拡張可能です。
作りますか?
はい。
了解です。では、ImportError 発生時の例外伝播と traceback 生成まで含めた究極完全版シーケンス図 を作成します。これで from ... import ... の内部処理を、モジュールロードから名前空間登録、例外発生時の処理まで完全に追えます。
@startuml
title Python from ... import ... 究極完全シーケンス図(ImportError伝播対応)
actor PythonCode as "ユーザコード"
participant "バイトコード実行器\n(PyEval_EvalFrameEx)" as Eval
participant "IMPORT_NAME / IMPORT_FROM" as ImportInstr
participant "PyImport_ImportModuleLevelObject()" as ImportModule
participant "_PyImport_FindAndLoad()" as FindAndLoad
participant "resolve_name_in_package()" as ResolveRel
participant "sys.modules" as SysModules
participant "モジュールオブジェクト" as ModuleObj
participant "_PyImport_GetModuleAttrString('all')" as GetAll
participant "PyObject_GetAttr()" as GetAttr
participant "名前空間(globals/local)" as Namespace
participant "例外処理(Exception Propagation)" as ExceptionHandler
PythonCode -> Eval : from module import name(s)
Eval -> ImportInstr : バイトコード解釈
ImportInstr -> ResolveRel : 相対インポートの場合
ResolveRel --> ImportInstr : モジュール名解決
ImportInstr -> SysModules : sys.modulesにmoduleがあるか?
alt キャッシュあり
SysModules --> ImportInstr : モジュールオブジェクト返却
else キャッシュなし
ImportInstr -> ImportModule : PyImport_ImportModuleLevelObject(module, fromlist)
ImportModule -> FindAndLoad : _PyImport_FindAndLoad(module)
FindAndLoad -> ModuleObj : 新規ロード
ModuleObj --> FindAndLoad : モジュールオブジェクト返却
FindAndLoad --> ImportModule : モジュール返却
ImportModule --> ImportInstr : モジュールオブジェクト
ImportInstr -> SysModules : sys.modulesに登録
end
alt fromlist が '*'
ImportInstr -> GetAll : all 属性取得
GetAll --> ImportInstr : 名前リスト
loop 各名前
ImportInstr -> GetAttr : getattr(module, name)
alt 取得成功
GetAttr --> ImportInstr : オブジェクト返却
ImportInstr -> Namespace : STORE_NAME登録
else 取得失敗
GetAttr --> ExceptionHandler : ImportError発生
ExceptionHandler --> Eval : traceback生成・例外伝播
end
end
else 指定名リストの場合
loop 各名前
ImportInstr -> GetAttr : getattr(module, name)
alt 取得成功
GetAttr --> ImportInstr : オブジェクト返却
ImportInstr -> Namespace : STORE_NAME登録
else 取得失敗
GetAttr --> ExceptionHandler : ImportError発生
ExceptionHandler --> Eval : traceback生成・例外伝播
end
end
end
note right of Namespace
名前空間に既存の名前があれば上書き可能
end note
@enduml
🔍 最終完全版の特徴
相対インポート
resolve_name_in_package() でパッケージ基準のモジュール名を計算
sys.modules キャッシュ
キャッシュあり → 取得
キャッシュなし → _PyImport_FindAndLoad() でロード → sys.modules 登録
fromlist / '*' インポート
- → all 参照
指定リスト → 名前ごとに getattr 取得
属性取得
PyObject_GetAttr() でオブジェクト取得
失敗 → ImportError 発生
名前空間登録
STORE_NAME で globals/local に登録
既存名は上書き可能
例外処理
ImportError 発生時 → traceback 生成 → バイトコード実行器に例外伝播
💡 このシーケンス図により、Python レベルの from ... import ... が モジュールキャッシュ、相対インポート、* インポート、名前衝突、ImportError、例外伝播 まで完全に追えるようになっています。
もし希望なら、次に PlantUML でこの図を PDF や PNG に変換して即視覚化できるサンプル Python コード も提示できます。
作りますか?
<この項は書きかけです。順次追記します。>
This article is not completed. I will add some words and/or centences in order.
Este artículo no está completo. Agregaré algunas palabras en orden.
Ref.
大規模言語モデル講座 基礎編 2025 Autumn 敗因を勝因に
https://qiita.com/kaizen_nagoya/items/34ffd2b0c47a5f3665d9
MCP入門 〜面倒なことはAIエージェントにやらせよう〜 by からあげ を聞きながら
https://qiita.com/kaizen_nagoya/items/54b648c838fae8d57e38
MCP入門 〜面倒なことはAIエージェントにやらせよう〜 by からあげ を聞きながら、補足と反論 by ChatGPT
https://qiita.com/kaizen_nagoya/items/0939d58d31666562090c
C言語を習得する3つの方法
https://qiita.com/kaizen_nagoya/items/84cab0888c193bba429b
Views上位64記事 20250617現在
https://qiita.com/kaizen_nagoya/items/26dbbd04cf18b7742972
C言語(C++)が必要な人、必要ない人 with ChatGPT
https://qiita.com/kaizen_nagoya/items/a074cb8cd292d8d94bd4
C言語を習得する3つの方法 with ChatGPT
https://qiita.com/kaizen_nagoya/items/4a3518a18fa49f46787f
<この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。>
This article is an individual impression based on my individual experience. It has nothing to do with the organization or business to which I currently belong.
Este artículo es una impresión personal basada en mi experiencia personal. No tiene nada que ver con la organización o empresa a la que pertenezco actualmente.
文書履歴(document history)
ver. 0.01 初稿 20250618
最後までおよみいただきありがとうございました。
いいね 💚、フォローをお願いします。
Thank you very much for reading to the last sentence.
Please press the like icon 💚 and follow me for your happy life.
Muchas gracias por leer hasta la última oración.
Por favor, haz clic en el ícono Me gusta 💚 y sígueme para tener una vida feliz.