> **Источник:** https://python-all.ru/3.4/library/mmap.html
>
> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.

---

# 18.9. [`mmap`](https://python-all.ru/3.4/library/mmap.html#module-mmap) – Поддержка файлов, отображаемых в память

Объекты файлов, отображаемых в память, ведут себя одновременно как [`bytearray`](https://python-all.ru/3.4/library/functions.html#bytearray) и как [*файловые объекты*](https://python-all.ru/3.4/glossary.html#term-file-object). Объекты mmap можно использовать в большинстве мест, где ожидаются [`bytearray`](https://python-all.ru/3.4/library/functions.html#bytearray); например, можно применять модуль [`re`](https://python-all.ru/3.4/library/re.html#module-re) для поиска в файле, отображённом в память. Можно также изменить один байт с помощью `obj[index] = 97`, или изменить подпоследовательность, присвоив значение срезу: `obj[i1:i2] = b'...'`. Также можно читать и записывать данные, начиная с tекущей позиции файла, и перемещаться `seek()` по файлу в разные позиции.

Файл, отображаемый в память, создаётся конструктором [`mmap`](https://python-all.ru/3.4/library/mmap.html#module-mmap), который различается в Unix и Windows. В любом случае необходимо предоставить файловый дескриптор файла, открытого для обновления. Если нужно отобразить существующий файловый объект Python, используйте его метод `fileno()`, чтобы получить правильное значение параметра *fileno*. В противном случае можно открыть файл с помощью функции [`os.open()`](https://python-all.ru/3.4/library/os.html#os.open), которая возвращает файловый дескриптор напрямую (файл всё равно нужно будет закрыть по завершении).

> **Примечание**
>
> Если необходимо создать отображение в память для буферизованного файла, доступного для записи, следует сначала выполнить [`flush()`](https://python-all.ru/3.4/library/io.html#io.IOBase.flush) для этого файла. Это необходимо, чтобы гарантировать, что локальные изменения буферов будут доступны отображению.

Для обеих версий конструктора (Unix и Windows) *access* может быть указан как необязательный именованный параметр. *access* принимает одно из трёх значений: `ACCESS_READ`, `ACCESS_WRITE` или `ACCESS_COPY`, которые задают соответственно память только для чтения, сквозную запись или копирование при записи. *access* можно использовать как в Unix, так и в Windows. Если *access* не указан, Windows mmap возвращает отображение со сквозной записью. Начальные значения памяти для всех трёх типов доступа берутся из указанного файла. Присваивание отображению памяти с `ACCESS_READ` вызывает исключение [`TypeError`](https://python-all.ru/3.4/library/exceptions.html#TypeError). Присваивание отображению памяти с `ACCESS_WRITE` затрагивает как память, так и базовый файл. Присваивание отображению памяти с `ACCESS_COPY` затрагивает память, но не обновляет базовый файл.

Для отображения анонимной памяти в качестве fileno следует передать -1 вместе с длиной.

#### `class mmap.mmap(fileno, length, tagname=None, access=ACCESS_DEFAULT[, offset])`

**(Версия Windows)** Отображает *length* байтов из файла, указанного файловым дескриптором *fileno*, и создаёт объект mmap. Если *length* больше текущего размера файла, файл расширяется до *length* байтов. Если *length* равно `0`, максимальная длина отображения равна текущему размеру файла, за исключением случая, когда файл пуст – тогда Windows вызывает исключение (нельзя создать пустое отображение в Windows).

*tagname*, если указан и не равен `None`, представляет собой строку, задающую имя тега для отображения. Windows позволяет иметь много разных отображений одного и того же файла. Если указать имя существующего тега, этот тег открывается, в противном случае создаётся новый тег с этим именем. Если этот параметр опущен или равен `None`, отображение создаётся без имени. Отказ от использования параметра tag поможет сохранить переносимость кода между Unix и Windows.

*offset* может быть задан как неотрицательное целое смещение. Ссылки mmap будут относительными к этому смещению от начала файла. *offset* по умолчанию равен 0. *offset* должен быть кратен ALLOCATIONGRANULARITY.

#### `class mmap.mmap(fileno, length, flags=MAP_SHARED, prot=PROT_WRITE|PROT_READ, access=ACCESS_DEFAULT[, offset])`

**(Версия Unix)** Отображает *length* байт из файла, заданного файловым дескриптором *fileno*, и возвращает объект mmap. Если *length* равен `0`, максимальная длина отображения будет равна текущему размеру файла на момент вызова [`mmap`](https://python-all.ru/3.4/library/mmap.html#module-mmap).

*flags* определяет характер отображения. `MAP_PRIVATE` создаёт частное отображение с копированием при записи, поэтому изменения содержимого объекта mmap будут частными для этого процесса, а `MAP_SHARED` создаёт отображение, которое используется совместно со всеми другими процессами, отображающими те же области файла. Значение по умолчанию – `MAP_SHARED`.

*prot*, если указан, задаёт желаемую защиту памяти; два наиболее полезных значения – `PROT_READ` и `PROT_WRITE`, которые указывают, что страницы можно читать или записывать. *prot* по умолчанию равен `PROT_READ | PROT_WRITE`.

*access* может быть указан вместо *flags* и *prot* как необязательный именованный параметр. Указывать одновременно *flags*, *prot* и *access* – ошибка. Информацию о том, как использовать этот параметр, см. в описании *access* выше.

*offset* может быть задан как неотрицательное целое смещение. Ссылки mmap будут относительными к этому смещению от начала файла. *offset* по умолчанию равен 0. *offset* должен быть кратен PAGESIZE или ALLOCATIONGRANULARITY.

Для обеспечения корректности созданного отображения в память файл, заданный дескриптором *fileno*, внутренне автоматически синхронизируется с физическим хранилищем на Mac OS X и OpenVMS.

В этом примере показан простой способ использования [`mmap`](https://python-all.ru/3.4/library/mmap.html#module-mmap):

```python
import mmap

# записать простой пример файла
with open("hello.txt", "wb") as f:
    f.write(b"Hello Python!\n")

with open("hello.txt", "r+b") as f:
    # отобразить файл в память, размер 0 означает весь файл
    mm = mmap.mmap(f.fileno(), 0)
    # прочитать содержимое с помощью стандартных методов файла
    print(mm.readline())  # выводит b"Hello Python!\n"
    # чтение содержимого с помощью срезовой нотации
    print(mm[:5])  # выводит b"Hello"
    # обновление содержимого с помощью срезовой нотации;
    # новое содержимое должно быть того же размера
    mm[6:] = b" world!\n"
    # ... и снова прочитать стандартными методами файлов
    mm.seek(0)
    print(mm.readline())  # выводит b"Hello  world!\n"
    # закрыть отображение
    mm.close()
```

[`mmap`](https://python-all.ru/3.4/library/mmap.html#module-mmap) также может использоваться как контекстный менеджер в операторе [`with`](https://python-all.ru/3.4/reference/compound_stmts.html#with):

```python
import mmap

with mmap.mmap(-1, 13) as mm:
    mm.write("Hello world!")
```

Новое в версии 3.2: Поддержка контекстного менеджера.

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

```python
import mmap
import os

mm = mmap.mmap(-1, 13)
mm.write(b"Hello world!")

pid = os.fork()

if pid == 0: # В дочернем процессе
    mm.seek(0)
    print(mm.readline())

    mm.close()
```

Объекты файлов с отображением в память поддерживают следующие методы:

#### `close()`

Закрывает mmap. Последующие вызовы других методов объекта приведут к возникновению исключения ValueError. Открытый файл при этом не закрывается.

#### `closed`

`True`, если файл закрыт.

Новое в версии 3.2.

#### `find(sub[, start[, end]])`

Возвращает наименьший индекс в объекте, где встречается подпоследовательность *sub*, при условии, что *sub* содержится в диапазоне \[*start*, *end*\]. Необязательные аргументы *start* и *end* интерпретируются как в записи среза. В случае неудачи возвращает `-1`.

#### `flush([offset[, size]])`

Сбрасывает изменения, внесённые в копию файла в памяти, обратно на диск. Без вызова этого метода нет гарантии, что изменения будут записаны до уничтожения объекта. Если указаны *offset* и *size*, на диск будут сброшены только изменения в заданном диапазоне байтов; в противном случае сбрасывается вся область отображения.

**(версия Windows)** Ненулевое возвращённое значение означает успех; нулевое – неудачу.

**(версия Unix)** Возвращается нулевое значение, означающее успех. При ошибке вызова возбуждается исключение.

#### `move(dest, src, count)`

Копирует *count* байт, начиная со смещения *src*, в целевой индекс *dest*. Если mmap был создан с `ACCESS_READ`, то вызовы move приведут к исключению [`TypeError`](https://python-all.ru/3.4/library/exceptions.html#TypeError).

#### `read([n])`

Возвращает [`bytes`](https://python-all.ru/3.4/library/functions.html#bytes), содержащий до *n* байт, начиная с текущей позиции файла. Если аргумент опущен, равен *None* или отрицателен, возвращаются все байты от текущей позиции файла до конца отображения. Позиция файла обновляется и указывает на байт после возвращённых данных.

Изменено в версии 3.3: Аргумент может быть опущен или равен *None*.

#### `read_byte()`

Возвращает байт в текущей позиции файла в виде целого числа и увеличивает позицию файла на 1.

#### `readline()`

Возвращает одну строку, начиная с текущей позиции в файле и до следующего символа новой строки.

#### `resize(newsize)`

Изменяет размер отображения и базового файла (если он есть). Если mmap был создан с `ACCESS_READ` или `ACCESS_COPY`, изменение размера вызовет исключение [`TypeError`](https://python-all.ru/3.4/library/exceptions.html#TypeError).

#### `rfind(sub[, start[, end]])`

Возвращает наибольший индекс в объекте, где найдена подпоследовательность *sub*, такой, что *sub* содержится в диапазоне \[*start*, *end*\]. Необязательные аргументы *start* и *end* интерпретируются как в нотации среза. Возвращает `-1` при неудаче.

#### `seek(pos[, whence])`

Устанавливает текущую позицию файла. Аргумент *whence* является необязательным и по умолчанию равен `os.SEEK_SET` или `0` (абсолютное позиционирование); другие значения: `os.SEEK_CUR` или `1` (смещение относительно текущей позиции) и `os.SEEK_END` или `2` (смещение относительно конца файла).

#### `size()`

Возвращает длину файла, которая может быть больше размера области отображения памяти.

#### `tell()`

Возвращает текущую позицию файлового указателя.

#### `write(bytes)`

Записывает байты из *bytes* в память в текущей позиции файлового указателя; позиция файла обновляется так, чтобы указывать после записанных байтов. Если mmap был создан с `ACCESS_READ`, то запись в него вызовет исключение [`TypeError`](https://python-all.ru/3.4/library/exceptions.html#TypeError).

#### `write_byte(byte)`

Записывает целое число *byte* в память в текущей позиции файлового указателя; позиция файла сдвигается на `1`. Если mmap был создан с `ACCESS_READ`, то запись в него вызовет исключение [`TypeError`](https://python-all.ru/3.4/library/exceptions.html#TypeError).
