Python: импорт исходных файлов с произвольными именами с помощью importlib

Я использую модуль imp для импорта модулей Python из исходного кода, учитывая абсолютное имя файла. т.е.

import imp
my_module = imp.load_source('my_module', '/paht/to/my_module')

Здесь /paht/to/my_module — это полный путь к файлу, содержащему исходный код Python, даже если он не имеет расширения .py.

При выполнении import imp в Python 3.7 отображается следующее предупреждение об устаревании:

DeprecationWarning: модуль imp устарел в пользу importlib; см. документацию модуля для альтернативного использования

Таким образом, я ищу importlib замену функции imp.load_source. Из документов у меня есть следующее:

import importlib.util
spec = importlib.util.spec_from_file_location('my_module', '/paht/to/my_module')
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)

Это не работает, когда имя файла не имеет расширения, как в моем случае. Я предполагаю, что это не удается, потому что ни один из реализованных «искателей» не распознает файл как исходный файл Python. Однако мне на самом деле не нужны все сложные механизмы, предоставляемые этими искателями, поскольку я уже точно знаю абсолютный путь к файлу. Я просто хочу, чтобы это было импортировано.

Простым хаком было бы просто прочитать исходный текст в виде текста и выполнить его вручную в своем собственном пространстве имен, что-то вроде

my_module = {} 
exec(open('/paht/to/my_module').read(), my_module)

(при этом имена, определенные в my_module, доступны через my_module['name'], а не my_module.name, но вы поняли идею). Я хотел бы знать, как это сделать правильно, используя importlib.


person jmd_dk    schedule 28.07.2018    source источник
comment
Возможный дубликат Импорт произвольного исходного файла Python. (Питон 3.3+)   -  person gmelodie    schedule 29.07.2018


Ответы (1)


Решение аналогичного вопроса опубликовано здесь. Перевел на мой пример:

import importlib.machinery, importlib.util
loader = importlib.machinery.SourceFileLoader('my_module', '/path/to/my_module')
spec = importlib.util.spec_from_loader(loader.name, loader)
my_module = importlib.util.module_from_spec(spec)
loader.exec_module(my_module)
person jmd_dk    schedule 28.07.2018