読者です 読者をやめる 読者になる 読者になる

cocuh's note

type(あうとぷっと) -> 駄文

__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でも同じコードを使っているため同じ挙動になります。