__import__とimportlib.import_moduleの挙動で躓いたこと
動的importで__import__とimportlibで挙動の違いで躓いたのでめもです。
packパッケージ内にplugin.pyをおいてあります。
# pack/plugin.py print("hoghoge!") def heyheyhey(): return
# pack/__init__.py
__import__では
>>> i = __import__('pack.plugin') hogehoge! >>> i <module 'pack' from 'pack/__init__.pyc'> >>> i.__name__ 'pack' >>> i.heyheyhey AttributeError >>> i.plugin.heyheyhey <function heyheyhey at 0x~~~~~~~~>
importlibのload_moduleでは
>>> i = importlib.load_module('pack.plugin') hogehoge! >>> i <module 'pack.plugin' from 'pack/plugin.pyc'> >>> i.__name__ 'plugins.pip' >>> i.heyheyhey <function heyheyhey at 0x~~~~~~~~>
おっ、
というわけで、__import__でパッケージをimportすると__init__.pyの方を。importlib.import_moduleではそのモジュールを返すのでつまづきました。
Python3.3でも試した感じおなじようでした。
reloadするときも気をつけないといけないです。
>>> i = __import__('pack.plugin') hogehoge! >>> i = __import__('pack.plugin') >>> reload(i) <module 'pack' from 'pack/__init__.pyc'> >>> reload(i.plugin) hogehoge! <module 'pack.plugin' from 'pack/plugin.pyc'>
>>> import importlib >>> i = importlib.import_module('pack.plugin') hogehoge! >>> i <module 'pack.plugin' from 'pack/plugin.pyc'> >>> reload(i) hogehoge! <module 'pack.plugin' from 'pack/plugin.pyc'>
ソースコードを読んでみるとどうしてこうなるかわかりました。
importlib.import_moduleは一度__import__(name)してsys.modules[name]で返してるからのようです。
python3.3でも同じコードを使っているため同じ挙動になります。