__import__の使い方

  • May 09, 2007 08:59

Djangoのソース読みから

pythonoでは設定ファイルで定めたモジュールをインポートするのに__import__関数を使うことが多いです。

たとえばdjango.db.__init__.pyでは

settingsで設定された

DATABASE_ENGINE = "mysql"

を受けて

django.db.backends.mysql.base

をインポートするのを

backend = __import__('django.db.backends.%s.base' % settings.DATABASE_ENGINE, {}, {}, [''])

のように書いてます。

__import__の引数は

__import__(name[, globals[, locals[, fromlist]]])

となっており、

import spam は __import__('spam', globals(), locals(), []) となり

from spam.ham import eggs は __import__('spam.ham', globals(), locals(), ['eggs']) となります。

上の例は

import django.db.backends.mysql.base as backend

と同等ということになります。(globals(), locals()は渡さないですが)

またgetattrと一緒に使われることが多く

django.core.handlerのbase.pyでは

for middleware_path in settings.MIDDLEWARE_CLASSES:
    dot = middleware_path.rindex('.')
    mw_module, mw_classname = middleware_path[:dot], middleware_path[dot+1:]
    mod = __import__(mw_module, {}, {}, [''])
    mw_class = getattr(mod, mw_classname)
    mw_instance = mw_class()
    #(例外処理を省いて簡素にしています)

のように使っています。

rindexは右からの位置を返す関数なので

django.contrib.sessions.middleware.SessionMiddleware

の場合

mw_module = "django.contrib.sessions.middleware"
mw_class = "SessionMiddleware"

となります

mod = __import__(mw_module, {}, {}, [''])

import django.contrib.sessions.middleware as mod

と同等で

getattr(mod, mw_classname)

mod.SessionMiddleware

と同等です。mod.SessionMiddlewareはクラスなので

mw_class = getattr(mod, mw_classname)
mw_instance = mw_class()

で、インスタンス化しています。

つまり

import django.contrib.sessions.middleware as mod
mw_instance = mod.SessionMiddleware() #mw_class は mod.SessionMiddleware

と同じという訳です。