Python 內建函式裡有一個 __import__(),可以用來自訂 package/module 的匯入 (import) 動作。Django 就利用這個函式來取得 DJANGO_SETTINGS_MODULE 和其它相關的功能模組。
當我們要在程式裡面設計可選擇的組件 (plugin) 時,讓它們被 __import__() 動態載入是蠻理想的方法。Python 官方文件裡對 __import__() 的介紹就給了一個剛好適用的範例:
def my_import(name): mod = __import__(name) components = name.split('.') for comp in components[1:]: mod = getattr(mod, comp) return mod
把模組的名稱字串 name 丟進 my_import() 去,就可以得到該字串所指涉的模組。這和一般所用的 import mod1.mod2 有什麼不一樣呢?我們寫:
import mod1.mod2
所得到的是一個 mod1 名稱,這個敘述會把 mod1 模組加進當前的命名空間中,同時把 mod2 加進 mod1 模組的命名空間;實際上,在當前的命名空間中得到的是 mod1 這個模組,而不是 mod2 。
my_import() 不一樣,當我們寫:
wantedmod = my_import( 'mod1.mod2' )
會把當前命名空間的 wantedmod 變數指定為 mod2 這一個模組。或者,也可以直接操作 my_import() 傳回的模組物件:
my_import( 'mod1.mod2' ).some_func_in_mod2()
當然,如果我們只是想要能夠比較方便地 mod2 這個模組,那麼:
from mod1 import mod2
或:
from mod1 import mod2 as wantedmod
都可以達成任務。使用 __import__() 的重要性在於,它可以在執行期決定要匯入的模組,不像 import 和 from foo import bar,撰寫程式的時候一定要把模組名稱寫死。
還想弄些更奇怪的操作?請使用 imp 模組來變魔法。