0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

python 16 words 4. from

Posted at

Pythonの用語を繰り返し唱えることにより、身につくかもっていう取り組みです。

from

used to show where somebody/something starts
https://www.oxfordlearnersdictionaries.com/definition/english/from?q=from

ChatGPT

pythonで from が機能する仕組みのソースコードを教えてください

なるほど。あなたは Python の from ... import ... 文が内部でどのように動作しているのか、その仕組みを「ソースコードレベルで」知りたいのですね。順を追って解説します。

  1. 基本の理解
    Python の from module import name は内部的には以下の処理を行います:
    指定されたモジュールを ロード する
    モジュール内のオブジェクト(関数・クラス・変数など)を取得する
    現在の名前空間にそのオブジェクトを登録する
    例:
    from math import sqrt
    は、ほぼ次のような処理です(擬似コード):
    import math # モジュールをロード
    sqrt = math.sqrt # 名前空間に追加
  2. 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 → 現在の名前空間に格納
  3. 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 キャッシュを使う
  4. 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.

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?