modules.md
1> **Источник:** https://python-all.ru/3.3/tutorial/modules.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 6. Модули89Если выйти из интерпретатора Python и войти в него снова, все созданные определения (функции и переменные) теряются. Поэтому для написания более длинной программы лучше использовать текстовый редактор для подготовки входных данных для интерпретатора и запускать его с этим файлом в качестве входных данных. Это называется созданием *скрипта*. По мере роста программы может потребоваться разбить её на несколько файлов для упрощения сопровождения. Также может пригодиться удобная функция, написанная для нескольких программ, без копирования её определения в каждую из них.1011Для поддержки этого в Python есть способ помещать определения в файл и использовать их в скрипте или в интерактивном сеансе интерпретатора. Такой файл называется *модулем*; определения из модуля можно *импортировать* в другие модули или в *главный* модуль (набор переменных, доступных в скрипте, выполняемом на верхнем уровне, и в режиме калькулятора).1213Модуль – это файл, содержащий определения и инструкции Python. Имя файла – это имя модуля с добавлением суффикса `.py`. Внутри модуля имя модуля (в виде строки) доступно как значение глобальной переменной `__name__`. Например, с помощью вашего любимого текстового редактора создайте файл с именем `fibo.py` в текущем каталоге со следующим содержимым:1415```python16# Модуль чисел Фибоначчи1718def fib(n): # вывести ряд Фибоначчи до n19 a, b = 0, 120 while b < n:21 print(b, end=' ')22 a, b = b, a+b23 print()2425def fib2(n): # возвращает ряд Фибоначчи до n26 result = []27 a, b = 0, 128 while b < n:29 result.append(b)30 a, b = b, a+b31 return result32```3334Теперь войдите в интерпретатор Python и импортируйте этот модуль с помощью следующей команды:3536```python37>>> import fibo38```3940Это не добавляет имена функций, определённых в `fibo`, непосредственно в текущую таблицу символов; оно добавляет только имя модуля `fibo`. Используя имя модуля, можно обращаться к функциям:4142```python43>>> fibo.fib(1000)441 1 2 3 5 8 13 21 34 55 89 144 233 377 610 98745>>> fibo.fib2(100)46[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]47>>> fibo.__name__48'fibo'49```5051Если вы намерены часто использовать функцию, можно присвоить её локальному имени:5253```python54>>> fib = fibo.fib55>>> fib(500)561 1 2 3 5 8 13 21 34 55 89 144 233 37757```5859## 6.1. Подробнее о модулях6061Модуль может содержать исполняемые инструкции, а также определения функций. Эти инструкции предназначены для инициализации модуля. Они выполняются только при *первом* обнаружении имени модуля в инструкции импорта. [\[1\]](https://python-all.ru/3.3/tutorial/modules.html#id2) (Они также запускаются, если файл выполняется как скрипт.)6263Каждый модуль имеет собственную приватную таблицу символов, которая используется как глобальная таблица символов всеми функциями, определёнными в модуле. Таким образом, автор модуля может использовать глобальные переменные в модуле, не беспокоясь о случайных конфликтах с глобальными переменными пользователя. С другой стороны, если вы знаете, что делаете, можно обращаться к глобальным переменным модуля, используя ту же нотацию, что и для обращения к его функциям: `modname.itemname`.6465Модули могут импортировать другие модули. Обычно, но не обязательно, размещать все инструкции [`import`](https://python-all.ru/3.3/reference/simple_stmts.html#import) в начале модуля (или, соответственно, скрипта). Имена импортированных модулей помещаются в глобальную таблицу символов импортирующего модуля.6667Существует разновидность инструкции [`import`](https://python-all.ru/3.3/reference/simple_stmts.html#import), которая импортирует имена из модуля непосредственно в таблицу символов импортирующего модуля. Например:6869```python70>>> from fibo import fib, fib271>>> fib(500)721 1 2 3 5 8 13 21 34 55 89 144 233 37773```7475При этом имя модуля, из которого берутся импорты, не вносится в локальную таблицу символов (поэтому в примере `fibo` не определён).7677Существует даже вариант импорта всех имён, определённых в модуле:7879```python80>>> from fibo import *81>>> fib(500)821 1 2 3 5 8 13 21 34 55 89 144 233 37783```8485Это импортирует все имена, кроме тех, которые начинаются с символа подчёркивания (`_`). В большинстве случаев программисты на Python не используют эту возможность, поскольку она вносит в интерпретатор неизвестный набор имён, что может скрыть уже определённые объекты.8687Обратите внимание, что в целом практика импортирования `*` из модуля или пакета не одобряется, поскольку часто приводит к плохо читаемому коду. Однако её можно использовать, чтобы сэкономить время набора в интерактивных сеансах.8889> **Примечание**90>91> Из соображений эффективности каждый модуль импортируется только один раз за сеанс интерпретатора. Поэтому, если вы изменили свои модули, необходимо перезапустить интерпретатор – или, если вы хотите интерактивно протестировать всего один модуль, используйте [`imp.reload()`](https://python-all.ru/3.3/library/imp.html#imp.reload), например `import imp; imp.reload(modulename)`.9293### 6.1.1. Выполнение модулей как скриптов9495Когда вы запускаете модуль Python с9697```python98python fibo.py <arguments>99```100101то код в модуле будет выполнен, как если бы вы его импортировали, но с `__name__`, установленным в `"__main__"`. Это означает, что, добавив этот код в конец вашего модуля:102103```python104if __name__ == "__main__":105 import sys106 fib(int(sys.argv[1]))107```108109можно сделать файл пригодным для использования как в качестве скрипта, так и импортируемого модуля, поскольку код, разбирающий командную строку, выполняется только при запуске модуля как «главного» файла:110111```python112$ python fibo.py 501131 1 2 3 5 8 13 21 34114```115116Если модуль импортируется, этот код не выполняется:117118```python119>>> import fibo120>>>121```122123Это часто используется либо для предоставления удобного пользовательского интерфейса модуля, либо для целей тестирования (запуск модуля как скрипта выполняет тестовый набор).124125### 6.1.2. Путь поиска модулей126127Когда импортируется модуль с именем `spam`, интерпретатор сначала ищет встроенный модуль с таким именем. Если он не найден, то ищется файл с именем `spam.py` в списке каталогов, заданном переменной [`sys.path`](https://python-all.ru/3.3/library/sys.html#sys.path). [`sys.path`](https://python-all.ru/3.3/library/sys.html#sys.path) инициализируется из следующих источников:128129- каталог, содержащий входной скрипт (или текущий каталог).130- [`PYTHONPATH`](https://python-all.ru/3.3/using/cmdline.html#envvar-PYTHONPATH) (список имён каталогов с тем же синтаксисом, что и переменная оболочки `PATH`).131- зависящий от установки путь по умолчанию.132133После инициализации программы на Python могут изменять [`sys.path`](https://python-all.ru/3.3/library/sys.html#sys.path). Каталог, содержащий выполняемый скрипт, помещается в начало пути поиска, перед путём стандартной библиотеки. Это означает, что скрипты из этого каталога будут загружаться вместо модулей с тем же именем из каталога библиотеки. Это ошибка, если только замена не предполагается. Дополнительную информацию см. в разделе [*Стандартные модули*](https://python-all.ru/3.3/tutorial/modules.html#tut-standardmodules).134135### 6.1.3. «Скомпилированные» файлы Python136137Чтобы ускорить загрузку модулей, Python кэширует скомпилированную версию каждого модуля в каталоге `__pycache__` под именем `module.version.pyc`, где version кодирует формат скомпилированного файла; обычно он содержит номер версии Python. Например, в CPython версии 3.3 скомпилированная версия spam.py была бы закэширована как `__pycache__/spam.cpython-33.pyc`. Такое соглашение об именах позволяет скомпилированным модулям из разных выпусков и разных версий Python сосуществовать.138139Python сверяет дату изменения исходного файла со скомпилированной версией, чтобы определить, устарела ли она и нуждается ли в перекомпиляции. Это полностью автоматический процесс. Кроме того, скомпилированные модули являются платформонезависимыми, поэтому одна и та же библиотека может использоваться в системах с разной архитектурой.140141Python не проверяет кеш в двух случаях. Во-первых, он всегда перекомпилирует и не сохраняет результат для модуля, загружаемого напрямую из командной строки. Во-вторых, он не проверяет кеш, если отсутствует исходный модуль. Чтобы поддержать распространение без исходников (только скомпилированные модули), скомпилированный модуль должен находиться в исходном каталоге, а исходный модуль должен отсутствовать.142143Несколько советов для экспертов:144145- Вы можете использовать флаги [*-O*](https://python-all.ru/3.3/using/cmdline.html#cmdoption-O) или [*-OO*](https://python-all.ru/3.3/using/cmdline.html#cmdoption-OO) в команде Python, чтобы уменьшить размер скомпилированного модуля. Флаг `-O` удаляет инструкции assert, а флаг `-OO` удаляет как инструкции assert, так и строки \_\_doc\_\_. Поскольку некоторые программы могут полагаться на их наличие, следует использовать эту опцию только если вы знаете, что делаете. «Оптимизированные» модули имеют суффикс .pyo, а не .pyc, и обычно меньше по размеру. Будущие выпуски могут изменить эффекты оптимизации.146- Программа не выполняется быстрее при чтении из файла `.pyc` или `.pyo`, чем при чтении из файла `.py`; единственное, что быстрее в файлах `.pyc` или `.pyo`, – это скорость их загрузки.147- Модуль [`compileall`](https://python-all.ru/3.3/library/compileall.html#module-compileall) может создавать файлы .pyc (или файлы .pyo при использовании [*-O*](https://python-all.ru/3.3/using/cmdline.html#cmdoption-O)) для всех модулей в каталоге.148- Более подробно этот процесс, включая блок-схему принятия решений, описан в PEP 3147.149150## 6.2. Стандартные модули151152Python поставляется с библиотекой стандартных модулей, описанной в отдельном документе – «Справочнике по библиотеке Python» (далее – «Справочник по библиотеке»). Некоторые модули встроены в интерпретатор; они предоставляют доступ к операциям, не являющимся частью ядра языка, но тем не менее встроенным – либо для эффективности, либо для обеспечения доступа к примитивам операционной системы, таким как системные вызовы. Набор таких модулей является опцией конфигурации, которая также зависит от базовой платформы. Например, модуль [`winreg`](https://python-all.ru/3.3/library/winreg.html#module-winreg) предоставляется только в системах Windows. Один модуль заслуживает особого внимания: [`sys`](https://python-all.ru/3.3/library/sys.html#module-sys), который встроен в каждый интерпретатор Python. Переменные `sys.ps1` и `sys.ps2` определяют строки, используемые в качестве основного и дополнительного приглашений:153154```python155>>> import sys156>>> sys.ps1157'>>> '158>>> sys.ps2159'... '160>>> sys.ps1 = 'C> '161C> print('Yuck!')162Yuck!163C>164```165166Эти две переменные определены только в том случае, если интерпретатор находится в интерактивном режиме.167168Переменная `sys.path` – это список строк, определяющий путь поиска модулей для интерпретатора. Она инициализируется путём по умолчанию, взятым из переменной окружения [`PYTHONPATH`](https://python-all.ru/3.3/using/cmdline.html#envvar-PYTHONPATH), или из встроенного значения по умолчанию, если [`PYTHONPATH`](https://python-all.ru/3.3/using/cmdline.html#envvar-PYTHONPATH) не задана. Её можно изменить с помощью стандартных операций со списками:169170```python171>>> import sys172>>> sys.path.append('/ufs/guido/lib/python')173```174175## 6.3. Функция [`dir()`](https://python-all.ru/3.3/library/functions.html#dir)176177Встроенная функция [`dir()`](https://python-all.ru/3.3/library/functions.html#dir) используется для выяснения, какие имена определяет модуль. Она возвращает отсортированный список строк:178179```python180>>> import fibo, sys181>>> dir(fibo)182['__name__', 'fib', 'fib2']183>>> dir(sys) 184['__displayhook__', '__doc__', '__egginsert', '__excepthook__',185 '__loader__', '__name__', '__package__', '__plen', '__stderr__',186 '__stdin__', '__stdout__', '_clear_type_cache', '_current_frames',187 '_debugmallocstats', '_getframe', '_home', '_mercurial', '_xoptions',188 'abiflags', 'api_version', 'argv', 'base_exec_prefix', 'base_prefix',189 'builtin_module_names', 'byteorder', 'call_tracing', 'callstats',190 'copyright', 'displayhook', 'dont_write_bytecode', 'exc_info',191 'excepthook', 'exec_prefix', 'executable', 'exit', 'flags', 'float_info',192 'float_repr_style', 'getcheckinterval', 'getdefaultencoding',193 'getdlopenflags', 'getfilesystemencoding', 'getobjects', 'getprofile',194 'getrecursionlimit', 'getrefcount', 'getsizeof', 'getswitchinterval',195 'gettotalrefcount', 'gettrace', 'hash_info', 'hexversion',196 'implementation', 'int_info', 'intern', 'maxsize', 'maxunicode',197 'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_cache',198 'platform', 'prefix', 'ps1', 'setcheckinterval', 'setdlopenflags',199 'setprofile', 'setrecursionlimit', 'setswitchinterval', 'settrace',200 'stderr', 'stdin', 'stdout', 'thread_info', 'version', 'version_info',201 'warnoptions']202```203204Без аргументов [`dir()`](https://python-all.ru/3.3/library/functions.html#dir) перечисляет имена, которые вы определили в данный момент:205206```python207>>> a = [1, 2, 3, 4, 5]208>>> import fibo209>>> fib = fibo.fib210>>> dir()211['__builtins__', '__name__', 'a', 'fib', 'fibo', 'sys']212```213214Обратите внимание, что она перечисляет имена всех типов: переменные, модули, функции и т.д.215216[`dir()`](https://python-all.ru/3.3/library/functions.html#dir) не перечисляет имена встроенных функций и переменных. Если вам нужен их список, они определены в стандартном модуле [`builtins`](https://python-all.ru/3.3/library/builtins.html#module-builtins):217218```python219>>> import builtins220>>> dir(builtins) 221['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException',222 'BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning',223 'ChildProcessError', 'ConnectionAbortedError', 'ConnectionError',224 'ConnectionRefusedError', 'ConnectionResetError', 'DeprecationWarning',225 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False',226 'FileExistsError', 'FileNotFoundError', 'FloatingPointError',227 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError',228 'ImportWarning', 'IndentationError', 'IndexError', 'InterruptedError',229 'IsADirectoryError', 'KeyError', 'KeyboardInterrupt', 'LookupError',230 'MemoryError', 'NameError', 'None', 'NotADirectoryError', 'NotImplemented',231 'NotImplementedError', 'OSError', 'OverflowError',232 'PendingDeprecationWarning', 'PermissionError', 'ProcessLookupError',233 'ReferenceError', 'ResourceWarning', 'RuntimeError', 'RuntimeWarning',234 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError',235 'SystemExit', 'TabError', 'TimeoutError', 'True', 'TypeError',236 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError',237 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning',238 'ValueError', 'Warning', 'ZeroDivisionError', '_', '__build_class__',239 '__debug__', '__doc__', '__import__', '__name__', '__package__', 'abs',240 'all', 'any', 'ascii', 'bin', 'bool', 'bytearray', 'bytes', 'callable',241 'chr', 'classmethod', 'compile', 'complex', 'copyright', 'credits',242 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'exec', 'exit',243 'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr',244 'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass',245 'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview',246 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property',247 'quit', 'range', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice',248 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars',249 'zip']250```251252## 6.4. Пакеты253254Пакеты – это способ структурирования пространства имён модулей Python с помощью «точечных имён модулей». Например, имя модуля `A.B` обозначает подмодуль с именем `B` в пакете с именем `A`. Подобно тому, как использование модулей избавляет авторов разных модулей от необходимости беспокоиться о глобальных переменных друг друга, использование точечных имён модулей избавляет авторов многомодульных пакетов, таких как NumPy или Python Imaging Library, от беспокойства об именах модулей друг друга.255256Предположим, вы хотите спроектировать набор модулей («пакет») для единообразной обработки звуковых файлов и звуковых данных. Существует множество различных форматов звуковых файлов (обычно определяемых по расширению, например: `.wav`, `.aiff`, `.au`), поэтому вам может потребоваться создать и поддерживать растущую коллекцию модулей для преобразования между различными форматами файлов. Также существует множество различных операций, которые вы, возможно, захотите выполнять со звуковыми данными (таких как микширование, добавление эха, применение эквалайзера, создание искусственного стереоэффекта), поэтому, вдобавок, вы будете писать бесконечный поток модулей для выполнения этих операций. Вот возможная структура вашего пакета (выраженная в терминах иерархической файловой системы):257258```text259sound/ Top-level package260 __init__.py Initialize the sound package261 formats/ Subpackage for file format conversions262 __init__.py263 wavread.py264 wavwrite.py265 aiffread.py266 aiffwrite.py267 auread.py268 auwrite.py269 ...270 effects/ Subpackage for sound effects271 __init__.py272 echo.py273 surround.py274 reverse.py275 ...276 filters/ Subpackage for filters277 __init__.py278 equalizer.py279 vocoder.py280 karaoke.py281 ...282```283284При импорте пакета Python просматривает каталоги по `sys.path` в поисках подкаталога пакета.285286Файлы `__init__.py` необходимы, чтобы Python рассматривал каталоги как содержащие пакеты; это сделано для предотвращения случайного скрытия каталогами с распространённым именем, например `string`, корректных модулей, находящихся позже в пути поиска модулей. В простейшем случае `__init__.py` может быть просто пустым файлом, но он также может выполнять код инициализации пакета или устанавливать переменную `__all__`, описанную далее.287288Пользователи пакета могут импортировать отдельные модули из пакета, например:289290```python291import sound.effects.echo292```293294Это загружает подмодуль `sound.effects.echo`. К нему необходимо обращаться по полному имени.295296```python297sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)298```299300Альтернативный способ импорта подмодуля:301302```python303from sound.effects import echo304```305306Это также загружает подмодуль `echo` и делает его доступным без префикса пакета, так что его можно использовать следующим образом:307308```python309echo.echofilter(input, output, delay=0.7, atten=4)310```311312Ещё один вариант – импортировать нужную функцию или переменную напрямую:313314```python315from sound.effects.echo import echofilter316```317318Опять же, это загружает подмодуль `echo`, но на этот раз делает его функцию `echofilter()` непосредственно доступной:319320```python321echofilter(input, output, delay=0.7, atten=4)322```323324Обратите внимание, что при использовании `from package import item` элемент может быть как подмодулем (или подпакетом) пакета, так и другим именем, определённым в пакете, например функцией, классом или переменной. Инструкция `import` сначала проверяет, определён ли элемент в пакете; если нет, она предполагает, что это модуль, и пытается его загрузить. Если его не удаётся найти, возбуждается исключение [`ImportError`](https://python-all.ru/3.3/library/exceptions.html#ImportError).325326Напротив, при использовании синтаксиса типа `import item.subitem.subsubitem` каждый элемент, кроме последнего, должен быть пакетом; последний элемент может быть модулем или пакетом, но не может быть классом, функцией или переменной, определённой в предыдущем элементе.327328### 6.4.1. Импорт \* из пакета329330Что же происходит, когда пользователь пишет `from sound.effects import *`? В идеале хотелось бы, чтобы это каким-то образом обращалось к файловой системе, находило, какие подмодули присутствуют в пакете, и импортировало их все. Это может занять много времени, а импорт подмодулей может иметь нежелательные побочные эффекты, которые должны возникать только при явном импорте подмодуля.331332Единственное решение – автору пакета предоставить явный индекс пакета. Инструкция [`import`](https://python-all.ru/3.3/reference/simple_stmts.html#import) использует следующее соглашение: если в коде `__init__.py` пакета определён список с именем `__all__`, он считается списком имён модулей, которые должны быть импортированы при встрече `from package import *`. Автор пакета должен поддерживать этот список в актуальном состоянии при выпуске новой версии пакета. Авторы пакетов могут также решить не поддерживать его, если не видят смысла в импорте \* из своего пакета. Например, файл `sound/effects/__init__.py` может содержать следующий код:333334```python335__all__ = ["echo", "surround", "reverse"]336```337338Это означает, что `from sound.effects import *` импортирует три указанных подмодуля пакета `sound`.339340Если `__all__` не определён, инструкция `from sound.effects import *` *не* импортирует все подмодули из пакета `sound.effects` в текущее пространство имён; она лишь гарантирует, что пакет `sound.effects` был импортирован (возможно, выполнив код инициализации из `__init__.py`), а затем импортирует все имена, определённые в пакете. Сюда входят любые имена, определённые (и явно загруженные подмодули) в `__init__.py`. А также все подмодули пакета, которые были явно загружены предыдущими инструкциями [`import`](https://python-all.ru/3.3/reference/simple_stmts.html#import). Рассмотрим такой код:341342```python343import sound.effects.echo344import sound.effects.surround345from sound.effects import *346```347348В этом примере модули `echo` и `surround` импортируются в текущее пространство имён, потому что они определены в пакете `sound.effects` при выполнении инструкции `from...import`. (Это работает и в том случае, если определён `__all__`.)349350Хотя некоторые модули спроектированы так, чтобы экспортировать только имена, соответствующие определённым шаблонам при использовании `import *`, в production-коде это всё равно считается плохой практикой.351352Помните: в использовании `from Package import specific_submodule` нет ничего плохого! Фактически это рекомендуемая форма записи, если только импортирующему модулю не нужны подмодули с одинаковыми именами из разных пакетов.353354### 6.4.2. Внутрипакетные ссылки355356Когда пакеты структурированы в подпакеты (как пакет `sound` в примере), можно использовать абсолютные импорты для обращения к подмодулям соседних пакетов. Например, если модулю `sound.filters.vocoder` нужен модуль `echo` из пакета `sound.effects`, он может использовать `from sound.effects import echo`.357358Можно также писать относительные импорты в форме `from module import name`. В таких импортах ведущие точки указывают на текущий и родительские пакеты. Например, из модуля `surround` можно использовать:359360```python361from . import echo362from .. import formats363from ..filters import equalizer364```365366Обратите внимание: относительные импорты основаны на имени текущего модуля. Поскольку имя главного модуля всегда `"__main__"`, модули, предназначенные для использования в качестве главного модуля приложения Python, всегда должны использовать абсолютные импорты.367368### 6.4.3. Пакеты в нескольких каталогах369370Пакеты поддерживают ещё один специальный атрибут – `__path__`. Он инициализируется списком, содержащим имя каталога, в котором находится `__init__.py` пакета, до выполнения кода в этом файле. Эту переменную можно изменять; это повлияет на последующий поиск модулей и подпакетов, содержащихся в пакете.371372Хотя эта возможность требуется нечасто, её можно использовать для расширения набора модулей, доступных в пакете.373374Сноски375376| [\[1\]](https://python-all.ru/3.3/tutorial/modules.html#id1) | На самом деле определения функций также являются «инструкциями», которые «выполняются»; исполнение определения функции на уровне модуля вносит имя функции в глобальную таблицу символов модуля. |377| --- | --- |378