モジュールの動的インポート
__import__()関数を使うと、モジュールを動的にインポートでき、コードの途中でインポートすることができます。例えば、
np = __import__("numpy")
np.random.rand()
# 0.2112903121866424
といったように。
普段あまり意識しませんが、numpyをインポートしているのにnumpy.randomが使えるのは、モジュールのトップレベルであるnumpyをインポートすると下位のモジュールのnumpy.randomも自動的にインポートされるからです。
xml.etree.ElementTreeの問題
しかしXMLを解析するモジュールであるxmlのサブモジュールxml.etree.ElementTreeを使おうと思って、この方法でxmlを動的にインポートするとエラーが出ます。
xml = __import__("xml")
xml_text = "<data> ナイスなデータ </data>"
root = xml.etree.ElementTree.fromstring(xml_text)
# TypeError: 'module' object is not callable
xmlにおいては、トップモジュールであるxmlをインポートしてもサブモジュールは自動でインポートされないようです。
さらに、__import__()関数は下位モジュールを指定してもトップモジュールをインポートします(参考:__import__のドキュメント)。つまりこうすることはできません。
ET = __import__("xml.etree.ElementTree")
xml_text = "<data> ナイスなデータ </data>"
root = ET.fromstring(xml_text)
# TypeError: 'module' object is not callable
このコードでは、上のコードと同様に変数ET内にはトップモジュールのxmlが入っています。
解決法
__import__()関数のドキュメントの注記にもあるように、__import__()関数ではなく、標準モジュールimportlibのimport_module()を使うことが推奨されているようです。
import importlib
ET = importlib.import_module("xml.etree.ElementTree")
xml_text = "<data> ナイスなデータ </data>"
root = ET.fromstring(xml_text)
import_module() 関数は importlib.__import__() を単純化するラッパーとして働きます。つまり、この関数のすべての意味は importlib.__import__() から受け継いでいます。これらの2つの関数の最も重要な違いは、 import_module() が指定されたパッケージやモジュール (例えば pkg.mod) を返すのに対し、__import__() はトップレベルのパッケージやモジュール (例えば pkg) を返すことです。
という記述があり(機械翻訳による)、import_moduleはサブモジュールを呼び出すための関数のようです。