Один из методов, которые я видел, в том числе в стандартной библиотеке, заключается в использовании import <em>module</em> as <em>_module</em>
или from <em>module</em> import <em>var</em> as <em>_var</em>
, т. Е. Присвоении импортированных модулей / переменных именам, начинающимся с подчеркивания.
В результате другой код, следуя обычному соглашению Python, обрабатывает эти элементы как частные. Это относится даже к коду, который не смотрит на __all__
, например, к функции автозаполнения IPython.
Пример из модуля Python 3.3 random
:
from warnings import warn as _warn
from types import MethodType as _MethodType, BuiltinMethodType as _BuiltinMethodType
from math import log as _log, exp as _exp, pi as _pi, e as _e, ceil as _ceil
from math import sqrt as _sqrt, acos as _acos, cos as _cos, sin as _sin
from os import urandom as _urandom
from collections.abc import Set as _Set, Sequence as _Sequence
from hashlib import sha512 as _sha512
Другой способ - выполнить импорт в области действия функции, чтобы они стали локальными переменными:
"""Some module"""
# imports conventionally go here
def some_function(arg):
"Do something with arg."
import re # Regular expressions solve everything
...
Основное обоснование для этого заключается в том, что он фактически ленив, задерживая импорт зависимостей модуля до тех пор, пока они не будут фактически использованы. Предположим, одна функция в модуле зависит от конкретной огромной библиотеки. Импорт библиотеки в верхней части файла будет означать, что импорт модуля загрузит всю библиотеку. Таким образом, импорт модуля может быть быстрым, и только клиентский код, который фактически вызывает эту функцию, несет расходы по загрузке библиотеки. Кроме того, если библиотека зависимостей недоступна, клиентский код, который не нуждается в зависимой функции, может импортировать модуль и вызывать другие функции. Недостатком является то, что использование импорта на уровне функций скрывает зависимости вашего кода.
Пример из Python 3.3 os.py
:
def get_exec_path(env=None):
"""[...]"""
# Use a local import instead of a global import to limit the number of
# modules loaded at startup: the os module is always loaded at startup by
# Python. It may also avoid a bootstrap issue.
import warnings