Как получить класс из модуля зная только его dotted-path?
Что за dotted-path? Это путь импорта через точки вроде такого:
"package.module.clsName"
Так как мы не можем закинуть строку в директиву import то повторим то, что она делает только "вручную"
mod = __import__('package.module', fromlist=['clsName'])
cls = getattr(mod, 'clsName')
Похожий способ с importlib
import importlib
module = importlib.import_module('package.module')
cls = getattr(module, 'clsName')
В обоих случаях приходится дополнительно обрабатывать строку чтобы отрезать имя класса от имени модуля. Так как мы сначала импортим модуль а потом достаём из него нужный объект.
Есть ли способ просто закинуть всю строку и получить результат?
Если пишете проект на Django то в нём есть функция import_string(). Она используется для импорта объектов, указанных в settings.py в виде dotted-path.
from django.utils.module_loading import import_string
cls = import_string('package.module.clsName')
Если же у вас "чистый" Python то на помощь придёт модуль pydoc. У него тоже есть аналогичный метод для импорта объектов по dotted-path.
from pydoc import locate
cls = locate('package.module.clsName')
В Python3.9 добавили еще один способ ресолвинга имени в объект. Теперь это самый актуальный способ на данный момент!
import pkgutil
cls = pkgutil.resolve_name('package.module.clsName')
____________
Конечно же это не относится только к классам. Точно так же можно импортнуть любой объект, вложенный в модуль.
#tricks