Насправді, поведінка в __import__()цілому пов'язана з реалізацією importзаяви, яка викликає __import__(). Там в основному п'ять кілька різних способів __import__()можуть бути викликані import(з двома основними категоріями):
import pkg
import pkg.mod
from pkg import mod, mod2
from pkg.mod import func, func2
from pkg.mod import submod
У першому і в другому випадку, то importоператор повинен призначити «найлівіший» об'єкт модуля до « крайнього лівого» імені: pkg. Після цього import pkg.modможна зробити, pkg.mod.func()оскільки в importоператорі введено локальне ім'я pkg, яке є об'єктом модуля, що має modатрибут. Отже, __import__()функція повинна повернути "самий лівий" об'єкт модуля, щоб його можна було призначити pkg. Таким чином, ці два оператори імпорту перекладаються на:
pkg = __import__('pkg')
pkg = __import__('pkg.mod')
У третьому, четвертому та п’ятому випадку importоператор повинен виконати більше роботи: він повинен призначити (потенційно) декілька імен, які він повинен отримати від об’єкта модуля. __import__()Функція може повертати тільки один об'єкт, і немає ніякої реальної причини , щоб зробити його отримати кожне з цих імен з об'єкта модуля (і це зробило б реалізацію набагато складніше.) Таким чином, простий підхід буде що - щось на зразок (для третього справа):
tmp = __import__('pkg')
mod = tmp.mod
mod2 = tmp.mod2
Однак це не буде працювати, якщо pkgце пакет і modабо mod2модулі в цьому пакеті, які ще не імпортовані , як це відбувається в третьому та п'ятому випадку. В __import__()потреби функції знати , що modі mod2є імена , що importзаява буде хочуть мати доступ до , так що він може побачити , якщо вони є модулі і спробувати імпортувати їх. Тож дзвінок ближче до:
tmp = __import__('pkg', fromlist=['mod', 'mod2'])
mod = tmp.mod
mod2 = tmp.mod2
який викликає , __import__()щоб спробувати навантаження pkg.modі pkg.mod2так само , як pkg(але якщо modабо mod2ні, це не помилка в __import__()виклику, виробляючи помилку залишається import. заяву) Але це ще не правильна річ для четвертої і п'ятий приклад, тому що якби дзвінок був таким:
tmp = __import__('pkg.mod', fromlist=['submod'])
submod = tmp.submod
тоді tmpв кінцевому підсумку буде pkgяк раніше, а не pkg.modмодулем, з якого ви хочете отримати submodатрибут. Реалізація могла б вирішити зробити це, щоб importоператор виконував додаткову роботу, розділяючи ім'я пакета, .як це __import__()вже робить функція, та обходячи імена, але це означало б дублювання деяких зусиль. Таким чином, замість того , реалізація MADE __import__()повернути праву більшість модуля замість самого лівих один , якщо і тільки якщо fromlist передається і не спустошити.
( Синтаксис import pkg as pand та from pkg import mod as mнічого не змінює в цій історії, крім того, яким місцевим іменам присвоюється - __import__()функція не бачить нічого іншого, коли asвикористовується, все залишається у реалізації importоператора.)