Найти в Дзене
Властелин машин

Динамическая загрузка модулей в Python и как она спасает при работе с pyspark

Оглавление

"Приобретение знаний - это как путешествие в неизведанные земли: чем больше вы исследуете, тем больше открытий вы делаете".

Библиотека importlib в Python предоставляет инструменты для динамической загрузки модулей. То есть она будет происходить не на этапе анализа кода интерпретатором, а во время выполнения программы. Это полезно, когда некоторые модули не известны до старта программы, например, как при работе с pyspark до инициализации переменных окружения с нужными путями.

Импорт модуля

Самый простой способ динамически загрузить модуль - использовать функцию import_module. Например, встроенный модуль math можно загрузить и использовать так:

Как указывал выше, этот способ спасет при работе с pyspark, вот как импортируются наиболее часто используемые модули:

F = importlib.import_module('pyspark.sql.functions')
T = importlib.import_module('pyspark.sql.types')

Теперь рассмотрим пользовательский модуль следующего содержания:

-2

Для его загрузки понадобится такой код:

-3

Так можно извлечь нужные нам переменные по некоторому правилу:

-4

Часто такое получение переменных применяется при тесте дагов Airflow (подробнее о vars можете прочитать тут):

from airflow import DAG
[k for k,v in vars(func_mod).items() if isinstance(v, DAG)]

Перезагрузка модуля

Если в нашем пользовательском модуле инициализировать дополнительную переменную (c), то потребуется перезагрузка модуля:

-5

Иначе мы не сможем обратиться к переменной:

-6

ни даже после повторной загрузки модуля:

-7

Это происходит из-за кеширования результатов загрузки модуля (подробнее смотри тут). Помочь может очистка специального словаря.

Так, для хранения информации о загруженных модулях используется словарь sys.modules. Когда модуль загружается, его имя добавляется в словарь. Это позволяет системе быстро определить, был ли модуль уже загружен или нет, чтобы избежать повторной загрузки и улучшить производительность.

Словарь sys.modules также может быть использован для управления процессом импорта, например, вы можете удалить оттуда запись о модуле, чтобы система его перезагрузила при очередном импорте:

-8

С функцией reload можно произвести перезагрузку модуля без манипуляций с sys.modules. Добавим еще одну переменную в наш модуль:

-9

Как и ожидалось, сначала она не доступна:

-10

Однако после вызова reload все встает на свои места:

-11

Спецификация модуля

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

Для получения объекта ModuleSpec, можно воспользоваться функцией find_spec модуля importlib.util:

-12
-13

Так можно загрузить сам модуль по объекту спецификации:

-14

Следует отметить, что этот способ не добавляет модуль в sys.modules:

-15

Однако ничто не мешает сделать это самим, если надо:

-16

-17

Наука
7 млн интересуются