Python 3.x でモジュールの動的importをする場合、 importlib.machinery.SourceFileLoader.load_module()
が便利でした。
import importlib.machinery as imm
datum = imm.SourceFileLoader('some', 'foo/some.py').load_module()
引用: モジュールの動的読み込み
しかし、Python3.6から Loader.load_module()
が非推奨になってしまいました1。load_module()
の機能のうち、モジュールオブジェクトの生成は create_module()
が、コードの実行は exec_module()
が引き継ぎ、sys.modules
の管理などはインポートシステムが裏で行うことになったようです。
ではPython3.6以降の動的importはどうするべきかというと、sys.meta_path
を一時的に変更するのが楽そうです。
import sys
from importlib import import_module
from importlib.abc import MetaPathFinder
from importlib.util import spec_from_file_location
def import_module_from_file_location(name, location):
class Finder(MetaPathFinder):
@staticmethod
def find_spec(fullname, *_):
if fullname == name:
return spec_from_file_location(name, location)
finder = Finder()
sys.meta_path.insert(0, finder)
try:
return import_module(name)
finally:
sys.meta_path.remove(finder)
mod = import_module_from_file_location('some', 'foo/some.py')