Документация Python неофициальный перевод

datamodel.md

1252 строк · 191.8 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/3.7/reference/datamodel.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 3. Модель данных89## 3.1. Объекты, значения и типы1011*Объекты* – это абстракция данных в Python. Все данные в программе Python представляются объектами или отношениями между объектами. (В некотором смысле, в соответствии с моделью фон Неймана «компьютера с хранимой программой», код также представляется объектами.)1213Каждый объект имеет идентичность, тип и значение. *Идентичность* объекта никогда не изменяется после его создания; её можно представлять как адрес объекта в памяти. Оператор '[`is`](https://python-all.ru/3.7/reference/expressions.html#is)' сравнивает идентичность двух объектов; функция [`id()`](https://python-all.ru/3.7/library/functions.html#id) возвращает целое число, представляющее его идентичность.1415**Особенность реализации CPython:** Для CPython `id(x)` – это адрес памяти, где хранится `x`.1617Тип объекта определяет, какие операции он поддерживает (например, «есть ли у него длина?»), а также задаёт возможные значения для объектов этого типа. Функция [`type()`](https://python-all.ru/3.7/library/functions.html#type) возвращает тип объекта (который сам является объектом). Как и идентификатор, *тип* объекта также неизменен. [1](https://python-all.ru/3.7/reference/datamodel.html#id8)1819*Значение* некоторых объектов может изменяться. Объекты, значение которых может изменяться, называются *изменяемыми*; объекты, значение которых неизменно после создания, называются *неизменяемыми*. (Значение неизменяемого объекта-контейнера, содержащего ссылку на изменяемый объект, может измениться при изменении последнего; однако контейнер всё равно считается неизменяемым, потому что набор содержащихся в нём объектов изменить нельзя. Таким образом, неизменяемость не тождественна неизменности значения – это тоньше.) Изменяемость объекта определяется его типом; например, числа, строки и кортежи неизменяемы, а словари и списки изменяемы.2021Объекты никогда не уничтожаются явно; однако, когда они становятся недостижимыми, они могут быть собраны сборщиком мусора. Реализация может откладывать сборку мусора или вовсе её не выполнять – качество реализации определяет, как именно реализована сборка мусора, при условии, что не собираются объекты, которые всё ещё достижимы.2223**Особенность реализации CPython:** В CPython в настоящее время используется схема подсчёта ссылок с (опциональным) отложенным обнаружением циклически связанного мусора, которая собирает большинство объектов, как только они становятся недостижимыми, но не гарантирует сборку мусора, содержащего циклические ссылки. Обратитесь к документации модуля [`gc`](https://python-all.ru/3.7/library/gc.html#module-gc) для получения информации об управлении сборкой циклического мусора. Другие реализации работают иначе, и CPython может измениться. Не полагайтесь на немедленную финализацию объектов после их становления недостижимыми (поэтому файлы всегда следует явно закрывать).2425Обратите внимание, что использование средств трассировки или отладки реализации может удерживать объекты в памяти, которые обычно подлежат сборке. Также обратите внимание, что перехват исключения с помощью оператора '[`try`](https://python-all.ru/3.7/reference/compound_stmts.html#try)…[`except`](https://python-all.ru/3.7/reference/compound_stmts.html#except)' может удерживать объекты в памяти.2627Некоторые объекты содержат ссылки на «внешние» ресурсы, такие как открытые файлы или окна. Подразумевается, что эти ресурсы освобождаются при сборке мусора объекта, но поскольку сборка мусора не гарантируется, такие объекты также предоставляют явный способ освобождения внешнего ресурса, обычно метод `close()`. Настоятельно рекомендуется явно закрывать такие объекты. Оператор '[`try`](https://python-all.ru/3.7/reference/compound_stmts.html#try)…[`finally`](https://python-all.ru/3.7/reference/compound_stmts.html#finally)' и оператор '[`with`](https://python-all.ru/3.7/reference/compound_stmts.html#with)' предоставляют удобные способы сделать это.2829Некоторые объекты содержат ссылки на другие объекты; они называются *контейнерами*. Примерами контейнеров являются кортежи, списки и словари. Ссылки являются частью значения контейнера. В большинстве случаев, когда мы говорим о значении контейнера, мы подразумеваем значения, а не идентификаторы содержащихся объектов; однако, когда мы говорим об изменяемости контейнера, подразумеваются только идентификаторы непосредственно содержащихся объектов. Таким образом, если неизменяемый контейнер (например, кортеж) содержит ссылку на изменяемый объект, его значение изменяется при изменении этого изменяемого объекта.3031Типы влияют почти на все аспекты поведения объектов. Даже важность идентичности объекта в некотором смысле затрагивается: для неизменяемых типов операции, вычисляющие новые значения, могут фактически возвращать ссылку на любой существующий объект с тем же типом и значением, в то время как для изменяемых объектов это не допускается. Например, после `a = 1; b = 1`, `a` и `b` могут ссылаться или не ссылаться на один и тот же объект со значением единицы, в зависимости от реализации, но после `c = []; d = []`, `c` и `d` гарантированно ссылаются на два разных, уникальных, только что созданных пустых списка. (Обратите внимание, что `c = d = []` присваивает один и тот же объект как `c`, так и `d`.)3233## 3.2. Стандартная иерархия типов3435Ниже приведён список типов, встроенных в Python. Модули расширения (написанные на C, Java или других языках в зависимости от реализации) могут определять дополнительные типы. Будущие версии Python могут добавлять типы в иерархию (например, рациональные числа, эффективно хранимые массивы целых чисел и т.д.), хотя такие дополнения чаще будут предоставляться через стандартную библиотеку.3637Некоторые описания типов ниже содержат абзац, перечисляющий «специальные атрибуты». Это атрибуты, обеспечивающие доступ к реализации и не предназначенные для общего использования. Их определение может измениться в будущем.3839**None**4041Этот тип имеет единственное значение. Существует только один объект с этим значением. Доступ к этому объекту осуществляется через встроенное имя `None`. Он используется для обозначения отсутствия значения во многих ситуациях, например, возвращается из функций, которые явно ничего не возвращают. Его логическое значение – ложь.4243**NotImplemented**4445Этот тип имеет единственное значение. Существует единственный объект с этим значением. Доступ к этому объекту осуществляется через встроенное имя `NotImplemented`. Числовые методы и методы расширенного сравнения должны возвращать это значение, если они не реализуют операцию для предоставленных операндов. (В этом случае интерпретатор попробует применить отражённую операцию или другой запасной вариант в зависимости от оператора.) Его истинностное значение – True.4647См. [Реализация арифметических операций](https://python-all.ru/3.7/library/numbers.html#implementing-the-arithmetic-operations) для получения дополнительных сведений.4849**Ellipsis**5051Этот тип имеет единственное значение. Существует только один объект с этим значением. Доступ к объекту осуществляется через литерал `...` или встроенное имя `Ellipsis`. Его логическое значение – истина.5253**[`numbers.Number`](https://python-all.ru/3.7/library/numbers.html#numbers.Number)**5455Они создаются числовыми литералами и возвращаются в результате работы арифметических операторов и встроенных арифметических функций. Числовые объекты неизменяемы; после создания их значение никогда не меняется. Числа в Python, конечно, тесно связаны с математическими числами, но подвержены ограничениям числового представления в компьютерах.5657Python различает целые числа, числа с плавающей запятой и комплексные числа:5859**[`numbers.Integral`](https://python-all.ru/3.7/library/numbers.html#numbers.Integral)**6061Они представляют элементы из математического множества целых чисел (положительных и отрицательных).6263Существует два типа целых чисел:6465Целые числа ([`int`](https://python-all.ru/3.7/library/functions.html#int))6667> Они представляют числа в неограниченном диапазоне, ограниченном лишь доступной (виртуальной) памятью. Для операций сдвига и маскирования используется двоичное представление, а отрицательные числа представляются в варианте дополнительного кода, который создаёт иллюзию бесконечной строки знаковых битов, уходящей влево.6869**Булевы значения ([`bool`](https://python-all.ru/3.7/library/functions.html#bool))**7071Они представляют истинностные значения False и True. Два объекта, представляющие значения `False` и `True`, являются единственными булевыми объектами. Булев тип является подтипом целочисленного типа, и булевы значения ведут себя как значения 0 и 1 соответственно почти во всех контекстах, за исключением того, что при преобразовании в строку возвращаются строки `"False"` или `"True"` соответственно.7273Правила представления целых чисел призваны давать наиболее осмысленную интерпретацию операций сдвига и маскирования, в которых участвуют отрицательные целые числа.7475**[`numbers.Real`](https://python-all.ru/3.7/library/numbers.html#numbers.Real) ([`float`](https://python-all.ru/3.7/library/functions.html#float))**7677Эти числа представляют собой машинные числа с плавающей запятой двойной точности. Допустимый диапазон и обработка переполнения определяются нижележащей архитектурой машины (и реализацией на C или Java). Python не поддерживает числа с плавающей запятой одинарной точности; экономия процессора и памяти, которая обычно является причиной их использования, ничтожна по сравнению с накладными расходами на использование объектов в Python, поэтому нет смысла усложнять язык двумя видами чисел с плавающей запятой.7879**[`numbers.Complex`](https://python-all.ru/3.7/library/numbers.html#numbers.Complex) ([`complex`](https://python-all.ru/3.7/library/functions.html#complex))**8081Они представляют комплексные числа как пару машинных чисел с плавающей запятой двойной точности. Те же предостережения применяются, что и для чисел с плавающей запятой. Действительная и мнимая части комплексного числа `z` могут быть получены через атрибуты только для чтения `z.real` и `z.imag`.8283**Последовательности**8485Они представляют собой конечные упорядоченные множества, индексированные неотрицательными числами. Встроенная функция [`len()`](https://python-all.ru/3.7/library/functions.html#len) возвращает количество элементов последовательности. Когда длина последовательности равна *n*, набор индексов содержит числа 0, 1, …, *n*-1. Элемент *i* последовательности *a* выбирается с помощью `a[i]`.8687Последовательности также поддерживают срезы: `a[i:j]` выбирает все элементы с индексом *k*, таким что *i* `<=` *k* `<` *j*. При использовании в качестве выражения срез представляет собой последовательность того же типа. Это подразумевает, что набор индексов перенумеровывается так, чтобы начинаться с 0.8889Некоторые последовательности также поддерживают «расширенную нарезку» с третьим параметром «шаг»: `a[i:j:k]` выбирает все элементы *a* с индексом *x*, где `x = i + n*k`, *n* `>=` `0` и *i* `<=` *x* `<` *j*.9091Последовательности различаются по изменяемости:9293**Неизменяемые последовательности**9495Объект неизменяемого типа последовательности не может измениться после создания. (Если объект содержит ссылки на другие объекты, эти другие объекты могут быть изменяемыми и могут изменяться; однако совокупность объектов, на которые непосредственно ссылается неизменяемый объект, измениться не может.)9697Следующие типы являются неизменяемыми последовательностями:9899**Строки**100101Строка – это последовательность значений, представляющих кодовые точки Unicode. Все кодовые точки в диапазоне `U+0000 - U+10FFFF` могут быть представлены в строке. В Python нет типа `char`; вместо этого каждая кодовая точка в строке представлена строковым объектом длины `1`. Встроенная функция [`ord()`](https://python-all.ru/3.7/library/functions.html#ord) преобразует кодовую точку из строковой формы в целое число в диапазоне `0 - 10FFFF`; [`chr()`](https://python-all.ru/3.7/library/functions.html#chr) преобразует целое число в диапазоне `0 - 10FFFF` в соответствующий строковый объект длины `1`. [`str.encode()`](https://python-all.ru/3.7/library/stdtypes.html#str.encode) может использоваться для преобразования [`str`](https://python-all.ru/3.7/library/stdtypes.html#str) в [`bytes`](https://python-all.ru/3.7/library/stdtypes.html#bytes) с использованием заданной текстовой кодировки, а [`bytes.decode()`](https://python-all.ru/3.7/library/stdtypes.html#bytes.decode) может использоваться для обратного преобразования.102103**Кортежи**104105Элементами кортежа могут быть произвольные объекты Python. Кортежи из двух и более элементов создаются списками выражений, разделённых запятыми. Кортеж из одного элемента («синглтон») можно создать, добавив запятую к выражению (выражение само по себе не создаёт кортеж, так как круглые скобки должны использоваться для группировки выражений). Пустой кортеж создаётся пустой парой круглых скобок.106107**Байты**108109Объект bytes – это неизменяемый массив. Его элементы – 8-битные байты, представленные целыми числами в диапазоне 0 \<= x \< 256. Литералы bytes (например, `b'abc'`) и встроенный конструктор [`bytes()`](https://python-all.ru/3.7/library/stdtypes.html#bytes) можно использовать для создания объектов bytes. Кроме того, объекты bytes можно декодировать в строки с помощью метода [`decode()`](https://python-all.ru/3.7/library/stdtypes.html#bytes.decode).110111**Изменяемые последовательности**112113Изменяемые последовательности можно изменять после их создания. Обозначения подписки и срезов можно использовать как цель для присваивания и операторов [`del`](https://python-all.ru/3.7/reference/simple_stmts.html#del) (удаление).114115В настоящее время существует два встроенных изменяемых типа последовательностей:116117**Списки**118119Элементами списка являются произвольные объекты Python. Списки создаются путём помещения списка выражений, разделённых запятыми, в квадратные скобки. (Обратите внимание, что для создания списков длины 0 или 1 не требуется особых случаев.)120121**Байтовые массивы**122123Объект bytearray – это изменяемый массив. Они создаются встроенным конструктором [`bytearray()`](https://python-all.ru/3.7/library/stdtypes.html#bytearray). Помимо изменяемости (и, следовательно, невозможности хеширования), байтовые массивы в остальном предоставляют тот же интерфейс и функциональность, что и неизменяемые объекты [`bytes`](https://python-all.ru/3.7/library/stdtypes.html#bytes).124125Модуль расширения [`array`](https://python-all.ru/3.7/library/array.html#module-array) предоставляет дополнительный пример изменяемого типа последовательности, как и модуль [`collections`](https://python-all.ru/3.7/library/collections.html#module-collections).126127**Типы множеств**128129Они представляют неупорядоченные, конечные множества уникальных, неизменяемых объектов. Поэтому к ним нельзя обратиться по индексу. Однако их можно перебирать, а встроенная функция [`len()`](https://python-all.ru/3.7/library/functions.html#len) возвращает количество элементов в множестве. Обычное применение множеств – быстрая проверка принадлежности, удаление дубликатов из последовательности и выполнение математических операций, таких как пересечение, объединение, разность и симметрическая разность.130131Для элементов множества действуют те же правила неизменяемости, что и для ключей словаря. Обратите внимание, что числовые типы следуют обычным правилам числового сравнения: если два числа считаются равными (например, `1` и `1.0`), только одно из них может содержаться в множестве.132133В настоящее время существует два встроенных типа множеств:134135**Множества**136137Они представляют изменяемое множество. Они создаются встроенным конструктором [`set()`](https://python-all.ru/3.7/library/stdtypes.html#set) и могут быть изменены впоследствии с помощью нескольких методов, таких как `add()`.138139**Неизменяемые множества**140141Они представляют неизменяемое множество. Они создаются встроенным конструктором [`frozenset()`](https://python-all.ru/3.7/library/stdtypes.html#frozenset). Поскольку frozenset неизменяем и [хешируем](https://python-all.ru/3.7/glossary.html#term-hashable), его можно снова использовать как элемент другого множества или как ключ словаря.142143**Отображения**144145Они представляют конечные наборы объектов, индексированных произвольными наборами индексов. Обозначение индекса `a[k]` выбирает элемент, индексированный `k`, из отображения `a`; это можно использовать в выражениях и как цель присваивания или операторов [`del`](https://python-all.ru/3.7/reference/simple_stmts.html#del). Встроенная функция [`len()`](https://python-all.ru/3.7/library/functions.html#len) возвращает количество элементов в отображении.146147В настоящее время существует один встроенный тип отображения:148149**Словари**150151Они представляют конечные наборы объектов, индексированных почти произвольными значениями. Единственные типы значений, неприемлемые в качестве ключей, – это значения, содержащие списки, словари или другие изменяемые типы, которые сравниваются по значению, а не по идентичности объекта. Причина в том, что эффективная реализация словарей требует, чтобы хеш-значение ключа оставалось постоянным. Числовые типы, используемые для ключей, подчиняются обычным правилам числового сравнения: если два числа считаются равными (например, `1` и `1.0`), то они могут использоваться взаимозаменяемо для индексации одной и той же записи словаря.152153Словари сохраняют порядок вставки, то есть ключи будут выдаваться в том же порядке, в котором они последовательно добавлялись в словарь. Замена существующего ключа не меняет порядок, однако удаление ключа и его повторная вставка добавит его в конец, а не сохранит на старом месте.154155Словари изменяемы; их можно создать с помощью обозначения `{...}` (см. раздел [Отображения словарей](https://python-all.ru/3.7/reference/expressions.html#dict)).156157Модули расширения [`dbm.ndbm`](https://python-all.ru/3.7/library/dbm.html#module-dbm.ndbm) и [`dbm.gnu`](https://python-all.ru/3.7/library/dbm.html#module-dbm.gnu) предоставляют дополнительные примеры типов отображений, как и модуль [`collections`](https://python-all.ru/3.7/library/collections.html#module-collections).158159Изменено в версии 3.7: В версиях Python до 3.6 словари не сохраняли порядок вставки. В CPython 3.6 порядок вставки сохранялся, но в то время это считалось деталью реализации, а не гарантией языка.160161**Вызываемые типы**162163Это типы, к которым применима операция вызова функции (см. раздел [Вызовы](https://python-all.ru/3.7/reference/expressions.html#calls)):164165**Определяемые пользователем функции**166167Объект пользовательской функции создаётся определением функции (см. раздел [Определения функций](https://python-all.ru/3.7/reference/compound_stmts.html#function)). Она должна вызываться со списком аргументов, содержащим то же количество элементов, что и список формальных параметров функции.168169Специальные атрибуты:170171| Атрибут | Значение |  |172| --- | --- | --- |173| `__doc__` | Строка документации функции или `None`, если недоступна; не наследуется подклассами. | Доступно для записи |174| [`__name__`](https://python-all.ru/3.7/library/stdtypes.html#definition.__name__) | Имя функции. | Доступно для записи |175| [`__qualname__`](https://python-all.ru/3.7/library/stdtypes.html#definition.__qualname__) | [Квалифицированное имя](https://python-all.ru/3.7/glossary.html#term-qualified-name) функции. Новое в версии 3.3. | Доступно для записи |176| `__module__` | Имя модуля, в котором была определена функция, или `None`, если недоступно. | Доступно для записи |177| `__defaults__` | Кортеж, содержащий значения аргументов по умолчанию для тех аргументов, у которых есть значения по умолчанию, или `None`, если ни один аргумент не имеет значения по умолчанию. | Доступно для записи |178| `__code__` | Объект кода, представляющий скомпилированное тело функции. | Доступно для записи |179| `__globals__` | Ссылка на словарь, содержащий глобальные переменные функции – глобальное пространство имён модуля, в котором функция была определена. | Только для чтения |180| [`__dict__`](https://python-all.ru/3.7/library/stdtypes.html#object.__dict__) | Пространство имён, поддерживающее произвольные атрибуты функции. | Доступно для записи |181| `__closure__` | `None` или кортеж ячеек, содержащих привязки для свободных переменных функции. См. ниже информацию об атрибуте `cell_contents`. | Только для чтения |182| `__annotations__` | Словарь, содержащий аннотации параметров. Ключи словаря – имена параметров, а `'return'` – для аннотации возвращаемого значения, если она указана. | Доступно для записи |183| `__kwdefaults__` | Словарь, содержащий значения по умолчанию для параметров, передаваемых только по ключу. | Доступно для записи |184185Большинство атрибутов, помеченных как «Доступно для записи», проверяют тип присваиваемого значения.186187Объекты функций также поддерживают получение и установку произвольных атрибутов, которые можно использовать, например, для присоединения метаданных к функциям. Для получения и установки таких атрибутов используется обычная точечная нотация. *Обратите внимание, что текущая реализация поддерживает атрибуты функций только для пользовательских функций. Атрибуты функций для встроенных функций могут быть добавлены в будущем.*188189Объект ячейки имеет атрибут `cell_contents`. Он может использоваться для получения значения ячейки, а также для установки значения.190191Дополнительную информацию об определении функции можно получить из её объекта code; см. описание внутренних типов ниже.192193**Методы экземпляра**194195Объект метода экземпляра сочетает в себе класс, экземпляр класса и любой вызываемый объект (обычно функцию, определённую пользователем).196197Специальные атрибуты только для чтения: `__self__` – объект экземпляра класса, `__func__` – объект функции; `__doc__` – документация метода (то же, что и `__func__.__doc__`); [`__name__`](https://python-all.ru/3.7/library/stdtypes.html#definition.__name__) – имя метода (то же, что и `__func__.__name__`); `__module__` – имя модуля, в котором определён метод, или `None`, если недоступно.198199Методы также поддерживают доступ (но не установку) произвольных атрибутов функции на базовом объекте функции.200201Объекты пользовательских методов могут создаваться при получении атрибута класса (возможно, через экземпляр этого класса), если этот атрибут является пользовательским объектом функции или объектом метода класса.202203Когда объект метода экземпляра создаётся путём извлечения пользовательского объекта функции из класса через один из его экземпляров, его атрибут `__self__` является экземпляром, и такой метод называется связанным. Атрибут `__func__` нового метода – это исходный объект функции.204205Когда пользовательский объект метода создаётся путём получения другого объекта метода из класса или экземпляра, поведение аналогично объекту функции, за исключением того, что атрибут `__func__` нового экземпляра – это не исходный объект метода, а его атрибут `__func__`.206207Когда объект метода экземпляра создаётся путём извлечения объекта метода класса из класса или экземпляра, его атрибут `__self__` является самим классом, а его атрибут `__func__` – объектом функции, лежащим в основе метода класса.208209При вызове объекта метода экземпляра вызывается базовая функция (`__func__`), при этом экземпляр класса (`__self__`) вставляется перед списком аргументов. Например, когда `C` – это класс, содержащий определение функции `f()`, а `x` – экземпляр `C`, вызов `x.f(1)` эквивалентен вызову `C.f(x, 1)`.210211Когда объект метода экземпляра создаётся на основе объекта метода класса, «экземпляр класса», хранящийся в `__self__`, на самом деле будет самим классом, так что вызов `x.f(1)` или `C.f(1)` эквивалентен вызову `f(C,1)`, где `f` – это базовая функция.212213Обратите внимание, что преобразование объекта функции в объект метода экземпляра происходит каждый раз при получении атрибута из экземпляра. В некоторых случаях полезной оптимизацией является присвоение атрибута локальной переменной и вызов этой локальной переменной. Также заметьте, что это преобразование происходит только для пользовательских функций; другие вызываемые объекты (и все невызываемые объекты) извлекаются без преобразования. Важно также отметить, что пользовательские функции, которые являются атрибутами экземпляра класса, не преобразуются в связанные методы; это происходит *только*, когда функция является атрибутом класса.214215**Функции-генераторы**216217Функция или метод, использующие оператор [`yield`](https://python-all.ru/3.7/reference/simple_stmts.html#yield) (см. раздел [Оператор yield](https://python-all.ru/3.7/reference/simple_stmts.html#yield)), называется *функцией-генератором*. При вызове такая функция всегда возвращает объект-итератор, который можно использовать для выполнения тела функции: вызов метода [`iterator.__next__()`](https://python-all.ru/3.7/library/stdtypes.html#iterator.__next__) итератора заставляет функцию выполняться до тех пор, пока она не предоставит значение с помощью оператора `yield`. Когда функция выполняет оператор [`return`](https://python-all.ru/3.7/reference/simple_stmts.html#return) или завершается, возбуждается исключение [`StopIteration`](https://python-all.ru/3.7/library/exceptions.html#StopIteration), и итератор достигает конца набора возвращаемых значений.218219**Корутинные функции**220221Функция или метод, определённые с помощью [`async def`](https://python-all.ru/3.7/reference/compound_stmts.html#async-def), называются *корутинной функцией*. Такая функция при вызове возвращает объект [корутины](https://python-all.ru/3.7/glossary.html#term-coroutine). Она может содержать выражения [`await`](https://python-all.ru/3.7/reference/expressions.html#await), а также инструкции [`async with`](https://python-all.ru/3.7/reference/compound_stmts.html#async-with) и [`async for`](https://python-all.ru/3.7/reference/compound_stmts.html#async-for). См. также раздел [Объекты корутин](https://python-all.ru/3.7/reference/datamodel.html#coroutine-objects).222223**Асинхронные функции-генераторы**224225Функция или метод, которые определяются с помощью [`async def`](https://python-all.ru/3.7/reference/compound_stmts.html#async-def) и используют оператор [`yield`](https://python-all.ru/3.7/reference/simple_stmts.html#yield), называются *асинхронной функцией-генератором*. При вызове такая функция возвращает асинхронный объект-итератор, который можно использовать в операторе [`async for`](https://python-all.ru/3.7/reference/compound_stmts.html#async-for) для выполнения тела функции.226227Вызов метода `aiterator.__anext__()` асинхронного итератора вернёт [ожидаемый объект](https://python-all.ru/3.7/glossary.html#term-awaitable), который при ожидании будет выполняться до тех пор, пока не предоставит значение с помощью выражения [`yield`](https://python-all.ru/3.7/reference/simple_stmts.html#yield). Когда функция выполняет пустой оператор [`return`](https://python-all.ru/3.7/reference/simple_stmts.html#return) или доходит до конца, возбуждается исключение [`StopAsyncIteration`](https://python-all.ru/3.7/library/exceptions.html#StopAsyncIteration), и асинхронный итератор достигает конца набора значений для выдачи.228229**Встроенные функции**230231Объект встроенной функции – это обёртка вокруг функции на C. Примерами встроенных функций являются [`len()`](https://python-all.ru/3.7/library/functions.html#len) и [`math.sin()`](https://python-all.ru/3.7/library/math.html#math.sin) ([`math`](https://python-all.ru/3.7/library/math.html#module-math) – стандартный встроенный модуль). Количество и тип аргументов определяются функцией на C. Специальные атрибуты только для чтения: `__doc__` – строка документации функции или `None`, если недоступно; [`__name__`](https://python-all.ru/3.7/library/stdtypes.html#definition.__name__) – имя функции; `__self__` установлено в `None` (но см. следующий пункт); `__module__` – имя модуля, в котором функция была определена, или `None`, если недоступно.232233**Встроенные методы**234235Это, по сути, другая форма встроенной функции, на этот раз содержащая объект, передаваемый функции на C как неявный дополнительный аргумент. Примером встроенного метода является `alist.append()`, если предположить, что *alist* – это объект списка. В этом случае специальный атрибут только для чтения `__self__` устанавливается на объект, обозначенный *alist*.236237**Классы**238239Классы являются вызываемыми. Обычно эти объекты выступают в роли фабрик для создания собственных экземпляров, но возможны варианты для типов классов, которые переопределяют [`__new__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__new__). Аргументы вызова передаются в [`__new__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__new__) и, в типичном случае, в [`__init__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__init__) для инициализации нового экземпляра.240241**Экземпляры классов**242243Экземпляры произвольных классов можно сделать вызываемыми, определив в их классе метод [`__call__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__call__).244245**Модули**246247Модули являются основной организационной единицей кода Python и создаются [системой импорта](https://python-all.ru/3.7/reference/import.html#importsystem), вызываемой либо оператором [`import`](https://python-all.ru/3.7/reference/simple_stmts.html#import), либо вызовом таких функций, как [`importlib.import_module()`](https://python-all.ru/3.7/library/importlib.html#importlib.import_module) и встроенной [`__import__()`](https://python-all.ru/3.7/library/functions.html#__import__). Объект модуля имеет пространство имён, реализованное объектом-словарём (этот словарь доступен через атрибут `__globals__` функций, определённых в модуле). Обращения к атрибутам преобразуются в поиск по этому словарю, например, `m.x` эквивалентно `m.__dict__["x"]`. Объект модуля не содержит объект кода, использованный для инициализации модуля (поскольку после завершения инициализации он не нужен).248249Присваивание атрибуту обновляет словарь пространства имён модуля; например, `m.x = 1` эквивалентно `m.__dict__["x"] = 1`.250251Предопределённые (записываемые) атрибуты: [`__name__`](https://python-all.ru/3.7/reference/import.html#__name__) – имя модуля; `__doc__` – строка документации модуля или `None`, если недоступно; `__annotations__` (необязательно) – словарь, содержащий [аннотации переменных](https://python-all.ru/3.7/glossary.html#term-variable-annotation), собранные во время выполнения тела модуля; [`__file__`](https://python-all.ru/3.7/reference/import.html#__file__) – путь к файлу, из которого был загружен модуль, если он был загружен из файла. Атрибут [`__file__`](https://python-all.ru/3.7/reference/import.html#__file__) может отсутствовать для некоторых типов модулей, например, для модулей C, статически слинкованных с интерпретатором; для модулей расширения, динамически загружаемых из разделяемой библиотеки, это путь к файлу разделяемой библиотеки.252253Специальный атрибут только для чтения: [`__dict__`](https://python-all.ru/3.7/library/stdtypes.html#object.__dict__) – это пространство имен модуля в виде объекта-словаря.254255**Особенность реализации CPython:** Из-за того, как CPython очищает словари модулей, словарь модуля будет очищен, когда модуль выйдет из области видимости, даже если на словарь ещё есть активные ссылки. Чтобы этого избежать, скопируйте словарь или держите модуль в памяти, пока используете его словарь напрямую.256257**Пользовательские классы**258259Пользовательские типы классов обычно создаются с помощью определений классов (см. раздел [Определения классов](https://python-all.ru/3.7/reference/compound_stmts.html#class)). Класс имеет пространство имен, реализованное в виде объекта-словаря. Ссылки на атрибуты класса преобразуются в поиск в этом словаре, например, `C.x` преобразуется в `C.__dict__["x"]` (хотя существует ряд хуков, которые позволяют искать атрибуты другими способами). Если имя атрибута не найдено там, поиск атрибута продолжается в базовых классах. Этот поиск в базовых классах использует порядок разрешения методов C3, который корректно работает даже при наличии структур наследования типа «ромб», где есть множественные пути наследования, ведущие к общему предку. Дополнительные сведения о C3 MRO, используемом Python, можно найти в документации, прилагаемой к выпуску 2.3, по адресу [https://www.python.org/download/releases/2.3/mro/](https://python-all.ru/3.7/reference/datamodel.html).260261Когда обращение к атрибуту класса (например, для класса `C`) возвращает объект метода класса, он преобразуется в объект метода экземпляра, чей атрибут `__self__` равен `C`. Когда оно возвращает объект статического метода, он преобразуется в объект, обёрнутый объектом статического метода. См. раздел [Реализация дескрипторов](https://python-all.ru/3.7/reference/datamodel.html#descriptors) для другого способа, которым атрибуты, получаемые из класса, могут отличаться от тех, что фактически содержатся в его [`__dict__`](https://python-all.ru/3.7/library/stdtypes.html#object.__dict__).262263Присваивание атрибутов класса обновляет словарь самого класса, но никогда не словарь базового класса.264265Объект класса можно вызвать (см. выше), чтобы получить экземпляр класса (см. ниже).266267Специальные атрибуты: [`__name__`](https://python-all.ru/3.7/library/stdtypes.html#definition.__name__) – имя класса; `__module__` – имя модуля, в котором класс определён; [`__dict__`](https://python-all.ru/3.7/library/stdtypes.html#object.__dict__) – словарь, содержащий пространство имён класса; [`__bases__`](https://python-all.ru/3.7/library/stdtypes.html#class.__bases__) – кортеж, содержащий базовые классы в порядке их перечисления в списке базовых классов; `__doc__` – строка документации класса или `None`, если не определена; `__annotations__` (необязательно) – словарь, содержащий [аннотации переменных](https://python-all.ru/3.7/glossary.html#term-variable-annotation), собранные во время выполнения тела класса.268269**Экземпляры классов**270271Экземпляр класса создаётся вызовом объекта класса (см. выше). Экземпляр класса имеет пространство имён, реализованное как словарь, который является первым местом, где ищутся ссылки на атрибуты. Если атрибут не найден там, и класс экземпляра имеет атрибут с таким именем, поиск продолжается среди атрибутов класса. Если найден атрибут класса, являющийся объектом пользовательской функции, он преобразуется в объект метода экземпляра, чьим атрибутом `__self__` является экземпляр. Объекты статического метода и метода класса также преобразуются; см. выше раздел «Классы». См. раздел [Реализация дескрипторов](https://python-all.ru/3.7/reference/datamodel.html#descriptors) для другого способа, которым атрибуты класса, полученные через его экземпляры, могут отличаться от объектов, фактически хранящихся в [`__dict__`](https://python-all.ru/3.7/library/stdtypes.html#object.__dict__) класса. Если атрибут класса не найден и у класса объекта есть метод [`__getattr__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__getattr__), он вызывается для удовлетворения поиска.272273Присваивания и удаления атрибутов обновляют словарь экземпляра, но никогда не словарь класса. Если у класса есть метод [`__setattr__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__setattr__) или [`__delattr__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__delattr__), он вызывается вместо прямого обновления словаря экземпляра.274275Экземпляры классов могут вести себя как числа, последовательности или отображения, если у них есть методы с определёнными специальными именами. См. раздел [Имена специальных методов](https://python-all.ru/3.7/reference/datamodel.html#specialnames).276277Специальные атрибуты: [`__dict__`](https://python-all.ru/3.7/library/stdtypes.html#object.__dict__) – словарь атрибутов; [`__class__`](https://python-all.ru/3.7/library/stdtypes.html#instance.__class__) – класс экземпляра.278279**Объекты ввода-вывода (также известные как файловые объекты)**280281[Файловый объект](https://python-all.ru/3.7/glossary.html#term-file-object) представляет открытый файл. Существуют различные краткие способы создания файловых объектов: встроенная функция [`open()`](https://python-all.ru/3.7/library/functions.html#open), а также [`os.popen()`](https://python-all.ru/3.7/library/os.html#os.popen), [`os.fdopen()`](https://python-all.ru/3.7/library/os.html#os.fdopen) и метод [`makefile()`](https://python-all.ru/3.7/library/socket.html#socket.socket.makefile) объектов сокетов (и, возможно, другие функции или методы, предоставляемые модулями расширения).282283Объекты `sys.stdin`, `sys.stdout` и `sys.stderr` инициализируются как файловые объекты, соответствующие стандартным потокам ввода, вывода и ошибок интерпретатора; все они открыты в текстовом режиме и поэтому следуют интерфейсу, определённому абстрактным классом [`io.TextIOBase`](https://python-all.ru/3.7/library/io.html#io.TextIOBase).284285**Внутренние типы**286287Некоторые типы, используемые внутри интерпретатора, доступны пользователю. Их определения могут измениться в будущих версиях интерпретатора, но здесь они упомянуты для полноты.288289**Объекты кода**290291Объекты кода представляют собой *скомпилированный в байт-код* исполняемый код Python, или [байт-код](https://python-all.ru/3.7/glossary.html#term-bytecode). Разница между объектом кода и объектом функции в том, что объект функции содержит явную ссылку на глобальные переменные функции (модуль, в котором она определена), тогда как объект кода не содержит контекста; кроме того, значения аргументов по умолчанию хранятся в объекте функции, а не в объекте кода (поскольку они представляют значения, вычисляемые во время выполнения). В отличие от объектов функций, объекты кода неизменяемы и не содержат ссылок (прямых или косвенных) на изменяемые объекты.292293Специальные атрибуты только для чтения: `co_name` – имя функции; `co_argcount` – количество позиционных аргументов (включая аргументы со значениями по умолчанию); `co_nlocals` – количество локальных переменных, используемых функцией (включая аргументы); `co_varnames` – кортеж, содержащий имена локальных переменных (начиная с имён аргументов); `co_cellvars` – кортеж, содержащий имена локальных переменных, на которые ссылаются вложенные функции; `co_freevars` – кортеж, содержащий имена свободных переменных; `co_code` – строка, представляющая последовательность инструкций байткода; `co_consts` – кортеж, содержащий литералы, используемые байткодом; `co_names` – кортеж, содержащий имена, используемые байткодом; `co_filename` – имя файла, из которого был скомпилирован код; `co_firstlineno` – номер первой строки функции; `co_lnotab` – строка, кодирующая отображение смещений байткода на номера строк (подробнее см. исходный код интерпретатора); `co_stacksize` – необходимый размер стека; `co_flags` – целое число, кодирующее набор флагов для интерпретатора.294295Для `co_flags` определены следующие битовые флаги: бит `0x04` установлен, если функция использует синтаксис `*arguments` для принятия произвольного числа позиционных аргументов; бит `0x08` установлен, если функция использует синтаксис `**keywords` для принятия произвольных ключевых аргументов; бит `0x20` установлен, если функция является генератором.296297Объявления будущих возможностей (`from __future__ import division`) также используют биты в `co_flags`, чтобы указать, был ли объект кода скомпилирован с включённой конкретной возможностью: бит `0x2000` установлен, если функция была скомпилирована с включённым future division; биты `0x10` и `0x1000` использовались в более ранних версиях Python.298299Остальные биты в `co_flags` зарезервированы для внутреннего использования.300301Если объект кода представляет функцию, первый элемент в `co_consts` – это строка документации функции, или `None`, если она не определена.302303**Объекты фреймов**304305Объекты фреймов представляют фреймы выполнения. Они могут встречаться в объектах трассировки стека (см. ниже), а также передаются зарегистрированным функциям трассировки.306307Специальные атрибуты только для чтения: `f_back` указывает на предыдущий фрейм стека (ближе к вызывающему) или `None`, если это нижний фрейм стека; `f_code` – объект кода, исполняемый в этом фрейме; `f_locals` – словарь, используемый для поиска локальных переменных; `f_globals` используется для глобальных переменных; `f_builtins` используется для встроенных (внутренних) имён; `f_lasti` представляет точную инструкцию (это индекс в строке байт-кода объекта кода).308309Специальные атрибуты для записи: `f_trace`, если не `None`, – это функция, вызываемая для различных событий во время выполнения кода (используется отладчиком). Обычно событие срабатывает для каждой новой строки исходного кода – это можно отключить, установив `f_trace_lines` в [`False`](https://python-all.ru/3.7/library/constants.html#False).310311Реализации *могут* разрешить запрос событий на каждую инструкцию, установив `f_trace_opcodes` в [`True`](https://python-all.ru/3.7/library/constants.html#True). Обратите внимание, что это может привести к неопределённому поведению интерпретатора, если исключения, возбуждённые функцией трассировки, выйдут в трассируемую функцию.312313`f_lineno` – текущий номер строки фрейма. Запись в него из функции трассировки вызывает переход на указанную строку (только для самого нижнего фрейма). Отладчик может реализовать команду Jump (также известную как Set Next Statement), записывая в f\_lineno.314315Объекты Frame поддерживают один метод:316317#### `frame.clear()`318319Этот метод очищает все ссылки на локальные переменные, хранящиеся во фрейме. Кроме того, если фрейм принадлежал генератору, генератор финализируется. Это помогает разорвать циклические ссылки с участием объектов фреймов (например, при перехвате исключения и сохранении его трассировки для дальнейшего использования).320321[`RuntimeError`](https://python-all.ru/3.7/library/exceptions.html#RuntimeError) возбуждается, если фрейм в данный момент выполняется.322323Новое в версии 3.4.324325**Объекты трассировки стека**326327Объекты трассировки стека представляют стековый след исключения. Объект трассировки стека неявно создаётся при возникновении исключения, а также может быть явно создан вызовом [`types.TracebackType`](https://python-all.ru/3.7/library/types.html#types.TracebackType).328329Для неявно созданных трассировок, когда поиск обработчика исключения разворачивает стек выполнения, на каждом развёрнутом уровне объект трассировки вставляется перед текущей трассировкой. Когда обработчик исключения входит в действие, стековый след становится доступен программе. (См. раздел [Инструкция try](https://python-all.ru/3.7/reference/compound_stmts.html#try).) Он доступен как третий элемент кортежа, возвращаемого `sys.exc_info()`, и как атрибут `__traceback__` перехваченного исключения.330331Если программа не содержит подходящего обработчика, трассировка стека выводится (в удобочитаемом формате) в стандартный поток ошибок; если интерпретатор работает в интерактивном режиме, она также становится доступной пользователю как `sys.last_traceback`.332333Для явно созданных трассировок создатель трассировки определяет, как атрибуты `tb_next` должны быть связаны, чтобы сформировать полный стековый след.334335Специальные атрибуты только для чтения: `tb_frame` указывает на фрейм выполнения текущего уровня; `tb_lineno` содержит номер строки, где произошло исключение; `tb_lasti` указывает точную инструкцию. Номер строки и последняя инструкция в трассировке могут отличаться от номера строки её объекта фрейма, если исключение произошло в инструкции [`try`](https://python-all.ru/3.7/reference/compound_stmts.html#try) без соответствующего предложения except или с предложением finally.336337Специальный атрибут для записи: `tb_next` – следующий уровень в стековом следе (в сторону фрейма, где произошло исключение), или `None`, если следующего уровня нет.338339Изменено в версии 3.7: Объекты трассировки стека теперь можно явно создавать из кода Python, и атрибут `tb_next` существующих экземпляров можно обновлять.340341**Объекты срезов**342343Объекты срезов используются для представления срезов для методов [`__getitem__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__getitem__). Они также создаются встроенной функцией [`slice()`](https://python-all.ru/3.7/library/functions.html#slice).344345Специальные атрибуты только для чтения: `start` – нижняя граница; `stop` – верхняя граница; `step` – шаг (значение); каждый равен `None`, если опущен. Эти атрибуты могут иметь любой тип.346347Объекты slice поддерживают один метод:348349#### `slice.indices(self, length)`350351Этот метод принимает единственный целочисленный аргумент *length* и вычисляет информацию о срезе, который объект среза описывал бы, если бы был применен к последовательности из *length* элементов. Он возвращает кортеж из трех целых чисел; соответственно это индексы *start* и *stop*, а также *step* или длина шага среза. Пропущенные или выходящие за границы индексы обрабатываются так же, как и для обычных срезов.352353**Объекты статических методов**354355Объекты статических методов предоставляют способ обойти преобразование объектов-функций в объекты-методы, описанное выше. Объект статического метода – это обёртка вокруг любого другого объекта, обычно определённого пользователем объекта-метода. Когда объект статического метода извлекается из класса или экземпляра класса, фактически возвращается обёрнутый объект, который не подвергается дальнейшим преобразованиям. Сами объекты статических методов не являются вызываемыми, хотя объекты, которые они оборачивают, обычно вызываемы. Объекты статических методов создаются встроенным конструктором [`staticmethod()`](https://python-all.ru/3.7/library/functions.html#staticmethod).356357**Объекты методов классов**358359Объект метода класса, как и объект статического метода, является обёрткой вокруг другого объекта, изменяющей способ получения этого объекта из классов и экземпляров классов. Поведение объектов методов класса при таком получении описано выше, в разделе «Пользовательские методы». Объекты методов классов создаются встроенным конструктором [`classmethod()`](https://python-all.ru/3.7/library/functions.html#classmethod).360361## 3.3. Специальные имена методов362363Класс может реализовать определённые операции, которые вызываются специальным синтаксисом (например, арифметические операции или индексация и срезы), путём определения методов со специальными именами. Это подход Python к *перегрузке операторов*, позволяющий классам определять собственное поведение для языковых операторов. Например, если класс определяет метод с именем [`__getitem__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__getitem__), а `x` – экземпляр этого класса, то `x[i]` примерно эквивалентно `type(x).__getitem__(x, i)`. Если не указано иное, попытка выполнить операцию вызывает исключение, когда не определён подходящий метод (обычно [`AttributeError`](https://python-all.ru/3.7/library/exceptions.html#AttributeError) или [`TypeError`](https://python-all.ru/3.7/library/exceptions.html#TypeError)).364365Установка специального метода в `None` означает, что соответствующая операция недоступна. Например, если класс устанавливает [`__iter__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__iter__) в `None`, класс не является итерируемым, поэтому вызов [`iter()`](https://python-all.ru/3.7/library/functions.html#iter) на его экземплярах вызовет исключение [`TypeError`](https://python-all.ru/3.7/library/exceptions.html#TypeError) (без обращения к [`__getitem__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__getitem__)). [2](https://python-all.ru/3.7/reference/datamodel.html#id9)366367При реализации класса, который эмулирует какой-либо встроенный тип, важно реализовывать эмуляцию только в той степени, в которой это имеет смысл для моделируемого объекта. Например, некоторые последовательности могут хорошо работать с получением отдельных элементов, но извлечение среза может не иметь смысла. (Одним из примеров этого является интерфейс `NodeList` в объектной модели документов W3C.)368369### 3.3.1. Базовая настройка370371#### `object.__new__(cls[, ...])`372373Вызывается для создания нового экземпляра класса *cls*. [`__new__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__new__) – это статический метод (специальный случай, поэтому его не нужно объявлять таковым), который принимает в качестве первого аргумента класс, для которого запрашивается экземпляр. Остальные аргументы – это те, что были переданы в выражение конструктора объекта (вызов класса). Возвращаемое значение [`__new__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__new__) должно быть новым экземпляром объекта (обычно экземпляром *cls*).374375Типичные реализации создают новый экземпляр класса, вызывая метод [`__new__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__new__) суперкласса с помощью `super().__new__(cls[, ...])` с соответствующими аргументами, а затем при необходимости изменяют только что созданный экземпляр перед его возвратом.376377Если [`__new__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__new__) возвращает экземпляр *cls*, то метод [`__init__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__init__) нового экземпляра будет вызван как `__init__(self[, ...])`, где *self* – новый экземпляр, а остальные аргументы те же, что были переданы [`__new__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__new__).378379Если [`__new__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__new__) не возвращает экземпляр *cls*, то метод [`__init__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__init__) нового экземпляра вызываться не будет.380381[`__new__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__new__) в первую очередь предназначен для того, чтобы подклассы неизменяемых типов (таких как int, str или tuple) могли настраивать создание экземпляров. Он также часто переопределяется в пользовательских метаклассах для настройки создания классов.382383#### `object.__init__(self[, ...])`384385Вызывается после создания экземпляра (с помощью [`__new__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__new__)), но до его возврата вызывающему. Аргументы – это те, что были переданы в выражение конструктора класса. Если базовый класс имеет метод [`__init__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__init__), то производный класс, если у него есть метод [`__init__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__init__), должен явно вызвать его, чтобы гарантировать правильную инициализацию части экземпляра, относящейся к базовому классу; например: `super().__init__([args...])`.386387Поскольку [`__new__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__new__) и [`__init__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__init__) работают вместе при создании объектов ([`__new__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__new__) создаёт его, а [`__init__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__init__) настраивает), метод [`__init__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__init__) не должен возвращать никакого значения, кроме `None`; в противном случае во время выполнения будет возбуждено исключение [`TypeError`](https://python-all.ru/3.7/library/exceptions.html#TypeError).388389#### `object.__del__(self)`390391Вызывается, когда экземпляр должен быть уничтожен. Это также называется финализатором или (некорректно) деструктором. Если базовый класс имеет метод [`__del__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__del__), то производный класс, если у него есть метод [`__del__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__del__), должен явно вызвать его, чтобы обеспечить корректное удаление части экземпляра, относящейся к базовому классу.392393Метод [`__del__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__del__) может (хотя это не рекомендуется!) отложить уничтожение экземпляра, создав на него новую ссылку. Это называется *воскрешением* объекта. Зависит от реализации, будет ли [`__del__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__del__) вызван второй раз, когда воскрешённый объект будет уничтожен; текущая реализация [CPython](https://python-all.ru/3.7/glossary.html#term-cpython) вызывает его только один раз.394395Нет гарантии, что методы [`__del__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__del__) будут вызваны для объектов, которые всё ещё существуют при завершении работы интерпретатора.396397> **Примечание**398>399> `del x` не вызывает напрямую `x.__del__()` – первая уменьшает счётчик ссылок на `x` на единицу, а вторая вызывается только тогда, когда счётчик ссылок `x` достигает нуля.400401**Особенность реализации CPython:** Циклическая ссылка может помешать счётчику ссылок объекта достичь нуля. В этом случае цикл будет позднее обнаружен и удалён [циклическим сборщиком мусора](https://python-all.ru/3.7/glossary.html#term-garbage-collection). Частая причина циклических ссылок – когда исключение было перехвачено в локальной переменной. Тогда локальные переменные фрейма ссылаются на исключение, которое ссылается на свою трассировку стека, а та, в свою очередь, ссылается на локальные переменные всех фреймов, захваченных в трассировку.402403> **См. также**404>405> Документация по модулю [`gc`](https://python-all.ru/3.7/library/gc.html#module-gc).406407> **Предупреждение**408>409> Из-за ненадёжных обстоятельств, при которых вызываются методы [`__del__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__del__), исключения, возникающие во время их выполнения, игнорируются, а вместо этого предупреждение выводится в `sys.stderr`. В частности:410>411> - [`__del__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__del__) может быть вызван во время выполнения произвольного кода, в том числе из любого произвольного потока. Если [`__del__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__del__) требуется захватить блокировку или обратиться к другому блокирующему ресурсу, может возникнуть взаимоблокировка, поскольку ресурс может уже быть занят кодом, который прерывается для выполнения [`__del__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__del__).412> - [`__del__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__del__) может выполняться во время завершения работы интерпретатора. В результате глобальные переменные, к которым ему нужно получить доступ (включая другие модули), могут уже быть удалены или установлены в `None`. Python гарантирует, что глобальные переменные, имена которых начинаются с одного символа подчёркивания, удаляются из своего модуля раньше, чем остальные; если других ссылок на такие глобальные переменные нет, это может помочь обеспечить доступность импортированных модулей на момент вызова метода [`__del__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__del__).413414#### `object.__repr__(self)`415416Вызывается встроенной функцией [`repr()`](https://python-all.ru/3.7/library/functions.html#repr) для вычисления «официального» строкового представления объекта. Если возможно, это представление должно выглядеть как допустимое выражение Python, которое можно использовать для воссоздания объекта с тем же значением (в подходящем окружении). Если это невозможно, следует вернуть строку вида `<...some useful description...>`. Возвращаемое значение должно быть строковым объектом. Если класс определяет [`__repr__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__repr__), но не [`__str__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__str__), то [`__repr__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__repr__) также используется, когда требуется «неформальное» строковое представление экземпляров этого класса.417418Обычно используется для отладки, поэтому важно, чтобы представление было информативным и однозначным.419420#### `object.__str__(self)`421422Вызывается функциями [`str(object)`](https://python-all.ru/3.7/library/stdtypes.html#str) и встроенными функциями [`format()`](https://python-all.ru/3.7/library/functions.html#format) и [`print()`](https://python-all.ru/3.7/library/functions.html#print) для вычисления «неформального» или хорошо читаемого строкового представления объекта. Возвращаемое значение должно быть объектом [строки](https://python-all.ru/3.7/library/stdtypes.html#textseq).423424Этот метод отличается от [`object.__repr__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__repr__) тем, что от [`__str__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__str__) не ожидается возврат корректного выражения Python: можно использовать более удобное или краткое представление.425426Реализация по умолчанию, определённая встроенным типом [`object`](https://python-all.ru/3.7/library/functions.html#object), вызывает [`object.__repr__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__repr__).427428#### `object.__bytes__(self)`429430Вызывается функцией [bytes](https://python-all.ru/3.7/library/functions.html#func-bytes) для вычисления байтового представления объекта. Должен возвращать объект [`bytes`](https://python-all.ru/3.7/library/stdtypes.html#bytes).431432#### `object.__format__(self, format_spec)`433434Вызывается встроенной функцией [`format()`](https://python-all.ru/3.7/library/functions.html#format), а также, соответственно, при вычислении [форматированных строковых литералов](https://python-all.ru/3.7/reference/lexical_analysis.html#f-strings) и метода [`str.format()`](https://python-all.ru/3.7/library/stdtypes.html#str.format) для получения «форматированного» строкового представления объекта. Аргумент *format\_spec* – это строка с описанием желаемых параметров форматирования. Интерпретация аргумента *format\_spec* зависит от типа, реализующего [`__format__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__format__), однако большинство классов либо делегируют форматирование одному из встроенных типов, либо используют похожий синтаксис параметров форматирования.435436См. [мини-язык спецификации формата](https://python-all.ru/3.7/library/string.html#formatspec) для описания стандартного синтаксиса форматирования.437438Возвращаемое значение должно быть строковым объектом.439440Изменено в версии 3.4: Метод \_\_format\_\_ самого `object` вызывает [`TypeError`](https://python-all.ru/3.7/library/exceptions.html#TypeError), если ему передана непустая строка.441442Изменено в версии 3.7: `object.__format__(x, '')` теперь эквивалентен `str(x)` вместо `format(str(self), '')`.443444#### `object.__lt__(self, other)`445446#### `object.__le__(self, other)`447448#### `object.__eq__(self, other)`449450#### `object.__ne__(self, other)`451452#### `object.__gt__(self, other)`453454#### `object.__ge__(self, other)`455456Это так называемые методы «расширенного сравнения». Соответствие между символами операторов и именами методов следующее: `x<y` вызывает `x.__lt__(y)`, `x<=y` вызывает `x.__le__(y)`, `x==y` вызывает `x.__eq__(y)`, `x!=y` вызывает `x.__ne__(y)`, `x>y` вызывает `x.__gt__(y)` и `x>=y` вызывает `x.__ge__(y)`.457458Метод расширенного сравнения может вернуть синглтон `NotImplemented`, если он не реализует операцию для данной пары аргументов. По соглашению, при успешном сравнении возвращаются `False` и `True`. Однако эти методы могут возвращать любое значение, поэтому если оператор сравнения используется в логическом контексте (например, в условии оператора `if`), Python вызовет [`bool()`](https://python-all.ru/3.7/library/functions.html#bool) для этого значения, чтобы определить, истинно оно или ложно.459460По умолчанию [`__ne__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__ne__) делегирует полномочия [`__eq__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__eq__) и инвертирует результат, если только он не равен `NotImplemented`. Между операторами сравнения нет других неявных связей: например, истинность `(x<y or x==y)` не влечёт `x<=y`. Для автоматической генерации операций упорядочивания из одной корневой операции см. [`functools.total_ordering()`](https://python-all.ru/3.7/library/functools.html#functools.total_ordering).461462Важные замечания по созданию [хешируемых](https://python-all.ru/3.7/glossary.html#term-hashable) объектов, поддерживающих пользовательские операции сравнения и пригодных для использования в качестве ключей словаря, см. в параграфе [`__hash__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__hash__).463464Не существует версий этих методов с переставленными аргументами (которые используются, когда левый аргумент не поддерживает операцию, а правый поддерживает); скорее, [`__lt__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__lt__) и [`__gt__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__gt__) являются отражением друг друга, [`__le__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__le__) и [`__ge__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__ge__) являются отражением друг друга, а [`__eq__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__eq__) и [`__ne__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__ne__) являются собственным отражением. Если операнды разных типов и тип правого операнда является прямым или косвенным подклассом типа левого операнда, то отражённый метод правого операнда имеет приоритет, в противном случае приоритет имеет метод левого операнда. Виртуальное подклассирование не учитывается.465466#### `object.__hash__(self)`467468Вызывается встроенной функцией [`hash()`](https://python-all.ru/3.7/library/functions.html#hash), а также при операциях с элементами хешируемых коллекций, включая [`set`](https://python-all.ru/3.7/library/stdtypes.html#set), [`frozenset`](https://python-all.ru/3.7/library/stdtypes.html#frozenset) и [`dict`](https://python-all.ru/3.7/library/stdtypes.html#dict). [`__hash__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__hash__) должен возвращать целое число. Единственное обязательное свойство: объекты, которые сравниваются как равные, должны иметь одинаковое хеш-значение. Рекомендуется смешивать хеш-значения компонентов объекта, которые также участвуют в сравнении объектов, упаковывая их в кортеж и вычисляя хеш от кортежа. Пример:469470```python471def __hash__(self):472    return hash((self.name, self.nick, self.color))473```474475> **Примечание**476>477> [`hash()`](https://python-all.ru/3.7/library/functions.html#hash) усекает значение, возвращаемое пользовательским методом [`__hash__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__hash__) объекта, до размера `Py_ssize_t`. Обычно это 8 байт в 64-битных сборках и 4 байта в 32-битных. Если [`__hash__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__hash__) объекта должна работать в сборках с разной разрядностью, обязательно проверьте ширину во всех поддерживаемых сборках. Простой способ сделать это – с помощью `python -c "import sys; print(sys.hash_info.width)"`.478479Если класс не определяет метод [`__eq__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__eq__), он не должен определять и операцию [`__hash__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__hash__); если он определяет [`__eq__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__eq__), но не [`__hash__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__hash__), его экземпляры нельзя будет использовать в качестве элементов хешируемых коллекций. Если класс определяет изменяемые объекты и реализует метод [`__eq__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__eq__), он не должен реализовывать [`__hash__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__hash__), поскольку реализация хешируемых коллекций требует, чтобы хеш-значение ключа было неизменяемым (если хеш-значение объекта изменится, он окажется в неправильном сегменте хеш-таблицы).480481Пользовательские классы по умолчанию имеют методы [`__eq__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__eq__) и [`__hash__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__hash__); с ними все объекты сравниваются как неравные (кроме сравнения с собой) и `x.__hash__()` возвращает подходящее значение, такое что `x == y` подразумевает как `x is y`, так и `hash(x) == hash(y)`.482483Класс, который переопределяет [`__eq__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__eq__) и не определяет [`__hash__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__hash__), будет иметь неявно установленный [`__hash__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__hash__) в `None`. Когда метод [`__hash__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__hash__) класса установлен в `None`, экземпляры класса будут вызывать соответствующее [`TypeError`](https://python-all.ru/3.7/library/exceptions.html#TypeError) при попытке программы получить их хеш-значение, а также будут правильно идентифицироваться как нехешируемые при проверке `isinstance(obj, collections.abc.Hashable)`.484485Если класс, переопределяющий [`__eq__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__eq__), должен сохранить реализацию [`__hash__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__hash__) от родительского класса, интерпретатору необходимо явно сообщить об этом, установив `__hash__ = <ParentClass>.__hash__`.486487Если класс, который не переопределяет [`__eq__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__eq__), хочет отключить поддержку хеширования, он должен включить `__hash__ = None` в определение класса. Класс, определяющий собственный [`__hash__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__hash__), который явно вызывает [`TypeError`](https://python-all.ru/3.7/library/exceptions.html#TypeError), будет ошибочно идентифицирован как хешируемый при вызове `isinstance(obj, collections.abc.Hashable)`.488489> **Примечание**490>491> По умолчанию значения [`__hash__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__hash__) объектов str, bytes и datetime «солятся» непредсказуемым случайным значением. Хотя они остаются постоянными в рамках одного процесса Python, их нельзя предсказать при повторных запусках Python.492>493> Это предназначено для защиты от отказа в обслуживании, вызванного специально подобранными входными данными, которые используют наихудшую производительность вставки в dict (сложность O(n^2)). Подробнее см. на [http://www.ocert.org/advisories/ocert-2011-003.html](https://python-all.ru/3.7/reference/datamodel.html).494>495> Изменение хеш-значений влияет на порядок перебора множеств. Python никогда не давал гарантий относительно этого порядка (и он обычно различается между 32-битными и 64-битными сборками).496>497> См. также [`PYTHONHASHSEED`](https://python-all.ru/3.7/using/cmdline.html#envvar-PYTHONHASHSEED).498499Изменено в версии 3.3: Рандомизация хешей включена по умолчанию.500501#### `object.__bool__(self)`502503Вызывается для реализации проверки истинности и встроенной операции `bool()`; должен возвращать `False` или `True`. Если этот метод не определён, вызывается [`__len__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__len__), если он определён, и объект считается истинным, если его результат не равен нулю. Если класс не определяет ни [`__len__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__len__), ни [`__bool__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__bool__), все его экземпляры считаются истинными.504505### 3.3.2. Настройка доступа к атрибутам506507Следующие методы могут быть определены для настройки смысла доступа к атрибутам (чтения, присваивания или удаления `x.name`) для экземпляров классов.508509#### `object.__getattr__(self, name)`510511Вызывается, когда обычный доступ к атрибуту завершается исключением [`AttributeError`](https://python-all.ru/3.7/library/exceptions.html#AttributeError) (либо [`__getattribute__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__getattribute__) вызывает [`AttributeError`](https://python-all.ru/3.7/library/exceptions.html#AttributeError), потому что *имя* не является атрибутом экземпляра или атрибутом в дереве классов для `self`; либо [`__get__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__get__) свойства *имя* вызывает [`AttributeError`](https://python-all.ru/3.7/library/exceptions.html#AttributeError)). Этот метод должен либо вернуть (вычисленное) значение атрибута, либо вызвать исключение [`AttributeError`](https://python-all.ru/3.7/library/exceptions.html#AttributeError).512513Обратите внимание, если атрибут найден через обычный механизм, [`__getattr__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__getattr__) не вызывается. (Это намеренная асимметрия между [`__getattr__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__getattr__) и [`__setattr__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__setattr__).) Это сделано как из соображений эффективности, так и потому, что в противном случае [`__getattr__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__getattr__) не имел бы способа получить доступ к другим атрибутам экземпляра. Обратите также внимание, что, по крайней мере, для переменных экземпляра можно имитировать полный контроль, не вставляя никаких значений в словарь атрибутов экземпляра (а вместо этого вставляя их в другой объект). См. метод [`__getattribute__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__getattribute__) ниже для способа действительно получить полный контроль над доступом к атрибутам.514515#### `object.__getattribute__(self, name)`516517Вызывается безусловно для реализации доступа к атрибутам экземпляров класса. Если класс также определяет [`__getattr__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__getattr__), последний не будет вызван, пока [`__getattribute__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__getattribute__) либо не вызовет его явно, либо не вызовет [`AttributeError`](https://python-all.ru/3.7/library/exceptions.html#AttributeError). Этот метод должен возвращать (вычисленное) значение атрибута или вызывать исключение [`AttributeError`](https://python-all.ru/3.7/library/exceptions.html#AttributeError). Чтобы избежать бесконечной рекурсии в этом методе, его реализация всегда должна вызывать метод базового класса с тем же именем для доступа к любым необходимым атрибутам, например, `object.__getattribute__(self, name)`.518519> **Примечание**520>521> Этот метод всё равно может быть обойдён при поиске специальных методов в результате неявного вызова через синтаксис языка или встроенные функции. См. [Поиск специальных методов](https://python-all.ru/3.7/reference/datamodel.html#special-lookup).522523#### `object.__setattr__(self, name, value)`524525Вызывается при попытке присвоения атрибута. Этот метод вызывается вместо обычного механизма (т.е. сохранения значения в словаре экземпляра). *name* – имя атрибута, *value* – значение, которое ему присваивается.526527Если [`__setattr__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__setattr__) хочет присвоить значение атрибуту экземпляра, он должен вызвать метод базового класса с тем же именем, например, `object.__setattr__(self, name, value)`.528529#### `object.__delattr__(self, name)`530531Как [`__setattr__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__setattr__), но для удаления атрибутов вместо присваивания. Этот метод следует реализовывать, только если `del obj.name` имеет смысл для объекта.532533#### `object.__dir__(self)`534535Вызывается, когда для объекта вызывается [`dir()`](https://python-all.ru/3.7/library/functions.html#dir). Должна быть возвращена последовательность. [`dir()`](https://python-all.ru/3.7/library/functions.html#dir) преобразует возвращённую последовательность в список и сортирует его.536537#### 3.3.2.1. Настройка доступа к атрибутам модуля538539Специальные имена `__getattr__` и `__dir__` также могут использоваться для настройки доступа к атрибутам модуля. Функция `__getattr__` на уровне модуля должна принимать один аргумент – имя атрибута – и возвращать вычисленное значение или вызывать исключение [`AttributeError`](https://python-all.ru/3.7/library/exceptions.html#AttributeError). Если атрибут не найден на объекте модуля через обычный поиск, т.е. [`object.__getattribute__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__getattribute__), то `__getattr__` ищется в модуле `__dict__` перед вызовом [`AttributeError`](https://python-all.ru/3.7/library/exceptions.html#AttributeError). Если найдена, она вызывается с именем атрибута, и результат возвращается.540541Функция `__dir__` не должна принимать аргументов и должна возвращать последовательность строк, представляющих имена, доступные в модуле. При наличии эта функция переопределяет стандартный поиск [`dir()`](https://python-all.ru/3.7/library/functions.html#dir) в модуле.542543Для более тонкой настройки поведения модуля (установка атрибутов, свойств и т.д.) можно установить атрибут `__class__` объекта модуля в подкласс [`types.ModuleType`](https://python-all.ru/3.7/library/types.html#types.ModuleType). Например:544545```python546import sys547from types import ModuleType548549class VerboseModule(ModuleType):550    def __repr__(self):551        return f'Verbose {self.__name__}'552553    def __setattr__(self, attr, value):554        print(f'Setting {attr}...')555        super().__setattr__(attr, value)556557sys.modules[__name__].__class__ = VerboseModule558```559560> **Примечание**561>562> Определение модуля `__getattr__` и установка модуля `__class__` влияют только на поиск через синтаксис доступа к атрибутам. Прямой доступ к глобальным переменным модуля (как из кода внутри модуля, так и через ссылку на словарь глобальных переменных модуля) не затрагивается.563564Изменено в версии 3.5: атрибут модуля `__class__` теперь доступен для записи.565566Новое в версии 3.7: `__getattr__` и `__dir__` – атрибуты модуля.567568> **См. также**569>570> **[**PEP 562**](https://python-all.ru/3.7/reference/datamodel.html) – Модули \_\_getattr\_\_ и \_\_dir\_\_**571>572> Описывает функции `__getattr__` и `__dir__` для модулей.573574#### 3.3.2.2. Реализация дескрипторов575576Следующие методы применяются только когда экземпляр класса, содержащего метод (так называемого *класса-дескриптора*), присутствует в *классе-владельце* (дескриптор должен быть либо в словаре класса владельца, либо в словаре класса одного из его родителей). В приведённых ниже примерах «атрибут» относится к атрибуту, имя которого является ключом свойства в словаре [`__dict__`](https://python-all.ru/3.7/library/stdtypes.html#object.__dict__) класса-владельца.577578#### `object.__get__(self, instance, owner)`579580Вызывается для получения атрибута класса-владельца (доступ к атрибуту класса) или экземпляра этого класса (доступ к атрибуту экземпляра). *owner* всегда является классом-владельцем, а *instance* – это экземпляр, через который был получен доступ к атрибуту, или `None`, когда доступ к атрибуту осуществляется через *owner*. Этот метод должен возвращать (вычисленное) значение атрибута или вызывать исключение [`AttributeError`](https://python-all.ru/3.7/library/exceptions.html#AttributeError).581582#### `object.__set__(self, instance, value)`583584Вызывается для установки атрибута экземпляра *instance* класса-владельца в новое значение *value*.585586#### `object.__delete__(self, instance)`587588Вызывается для удаления атрибута экземпляра *instance* класса-владельца.589590#### `object.__set_name__(self, owner, name)`591592Вызывается при создании класса-владельца *owner*. Дескриптор был присвоен *name*.593594> **Примечание**595>596> [`__set_name__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__set_name__) вызывается только неявно как часть конструктора [`type`](https://python-all.ru/3.7/library/functions.html#type), поэтому, когда дескриптор добавляется в класс после первоначального создания, его необходимо вызывать явно с соответствующими параметрами:597>598> ```python599> class A:600>    pass601> descr = custom_descriptor()602> A.attr = descr603> descr.__set_name__(A, 'attr')604> ```605>606> Подробнее см. [Создание объекта класса](https://python-all.ru/3.7/reference/datamodel.html#class-object-creation).607608Новое в версии 3.6.609610Атрибут `__objclass__` интерпретируется модулем [`inspect`](https://python-all.ru/3.7/library/inspect.html#module-inspect) как указание класса, в котором был определён этот объект (правильная установка может помочь при интроспекции динамических атрибутов класса во время выполнения). Для вызываемых объектов он может указывать, что в качестве первого позиционного аргумента ожидается или требуется экземпляр указанного типа (или подкласса) (например, CPython устанавливает этот атрибут для несвязанных методов, реализованных на C).611612#### 3.3.2.3. Вызов дескрипторов613614В общем, дескриптор – это атрибут объекта с «поведением связывания», доступ к атрибуту которого переопределён методами протокола дескриптора: [`__get__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__get__), [`__set__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__set__) и [`__delete__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__delete__). Если для объекта определён хотя бы один из этих методов, он считается дескриптором.615616Поведение по умолчанию при доступе к атрибуту – получение, установка или удаление атрибута из словаря объекта. Например, `a.x` имеет цепочку поиска, начинающуюся с `a.__dict__['x']`, затем `type(a).__dict__['x']`, и продолжающуюся по базовым классам `type(a)`, исключая метаклассы.617618Однако, если найденное значение является объектом, определяющим один из методов дескриптора, то Python может переопределить поведение по умолчанию и вместо этого вызвать метод дескриптора. Где именно это происходит в цепочке приоритетов, зависит от того, какие методы дескриптора определены и как они были вызваны.619620Отправная точка для вызова дескриптора – привязка, `a.x`. Способ сборки аргументов зависит от `a`:621622**Прямой вызов**623624Самый простой и наименее распространённый случай – когда пользовательский код напрямую вызывает метод дескриптора: `x.__get__(a)`.625626**Привязка к экземпляру**627628При привязке к экземпляру объекта `a.x` преобразуется в вызов: `type(a).__dict__['x'].__get__(a, type(a))`.629630**Привязка к классу**631632При привязке к классу `A.x` преобразуется в вызов: `A.__dict__['x'].__get__(None, A)`.633634**Привязка через super**635636Если `a` является экземпляром [`super`](https://python-all.ru/3.7/library/functions.html#super), то связывание `super(B, obj).m()` выполняет поиск в `obj.__class__.__mro__` базового класса `A`, непосредственно предшествующего `B`, а затем вызывает дескриптор с помощью вызова: `A.__dict__['m'].__get__(obj, obj.__class__)`.637638Для привязки к экземплярам приоритет вызова дескриптора зависит от того, какие методы дескриптора определены. Дескриптор может определять любую комбинацию [`__get__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__get__), [`__set__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__set__) и [`__delete__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__delete__). Если он не определяет [`__get__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__get__), то при обращении к атрибуту будет возвращён сам объект дескриптора, если только в словаре экземпляра нет соответствующего значения. Если дескриптор определяет [`__set__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__set__) и/или [`__delete__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__delete__), это дескриптор данных; если не определяет ни того, ни другого – это дескриптор не-данных. Обычно дескрипторы данных определяют и [`__get__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__get__), и [`__set__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__set__), а дескрипторы не-данных – только метод [`__get__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__get__). Дескрипторы данных с определёнными [`__set__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__set__) и [`__get__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__get__) всегда переопределяют переопределение в словаре экземпляра. В отличие от них, дескрипторы не-данных могут быть переопределены экземплярами.639640Методы Python (включая [`staticmethod()`](https://python-all.ru/3.7/library/functions.html#staticmethod) и [`classmethod()`](https://python-all.ru/3.7/library/functions.html#classmethod)) реализованы как дескрипторы без данных. Соответственно, экземпляры могут переопределять и заменять методы. Это позволяет отдельным экземплярам приобретать поведение, отличное от других экземпляров того же класса.641642Функция [`property()`](https://python-all.ru/3.7/library/functions.html#property) реализована как дескриптор данных. Соответственно, экземпляры не могут переопределить поведение свойства.643644#### 3.3.2.4. \_\_slots\_\_645646*\_\_slots\_\_* позволяет явно объявлять члены данных (например, свойства) и запрещает создание *\_\_dict\_\_* и *\_\_weakref\_\_* (если только они не объявлены явно в *\_\_slots\_\_* или не доступны в родительском классе).647648Экономия места по сравнению с использованием *\_\_dict\_\_* может быть значительной. Скорость поиска атрибутов также может быть значительно улучшена.649650#### `object.__slots__`651652Этой переменной класса можно присвоить строку, итерируемый объект или последовательность строк с именами переменных, используемых экземплярами. *\_\_slots\_\_* резервирует место для объявленных переменных и предотвращает автоматическое создание *\_\_dict\_\_* и *\_\_weakref\_\_* для каждого экземпляра.653654##### 3.3.2.4.1. Примечания по использованию *\_\_slots\_\_*655656- При наследовании от класса без *\_\_slots\_\_* атрибуты *\_\_dict\_\_* и *\_\_weakref\_\_* экземпляров всегда будут доступны.657- Без переменной *\_\_dict\_\_* экземплярам нельзя присваивать новые переменные, не перечисленные в определении *\_\_slots\_\_*. Попытки присвоить имя переменной, не указанной в списке, вызывают [`AttributeError`](https://python-all.ru/3.7/library/exceptions.html#AttributeError). Если требуется динамическое присваивание новых переменных, добавьте `'__dict__'` в последовательность строк в объявлении *\_\_slots\_\_*.658- Без переменной *\_\_weakref\_\_* для каждого экземпляра классы, определяющие *\_\_slots\_\_*, не поддерживают слабые ссылки на свои экземпляры. Если требуется поддержка слабых ссылок, добавьте `'__weakref__'` в последовательность строк в объявлении *\_\_slots\_\_*.659- *\_\_slots\_\_* реализуются на уровне класса путём создания дескрипторов ([Реализация дескрипторов](https://python-all.ru/3.7/reference/datamodel.html#descriptors)) для каждого имени переменной. В результате атрибуты класса нельзя использовать для установки значений по умолчанию для переменных экземпляра, определённых *\_\_slots\_\_*; в противном случае атрибут класса перезаписал бы присваивание дескриптора.660- Действие объявления *\_\_slots\_\_* не ограничивается классом, в котором оно определено. *\_\_slots\_\_*, объявленные в родительских классах, доступны в дочерних классах. Однако дочерние подклассы получат *\_\_dict\_\_* и *\_\_weakref\_\_*, если только они также не определяют *\_\_slots\_\_* (который должен содержать только имена любых *дополнительных* слотов).661- Если класс определяет слот, который также определён в базовом классе, переменная экземпляра, определённая слотом базового класса, становится недоступной (за исключением прямого получения её дескриптора из базового класса). Это делает поведение программы неопределённым. В будущем может быть добавлена проверка для предотвращения такой ситуации.662- Непустой *\_\_slots\_\_* не работает для классов, производных от встроенных типов «переменной длины», таких как [`int`](https://python-all.ru/3.7/library/functions.html#int), [`bytes`](https://python-all.ru/3.7/library/stdtypes.html#bytes) и [`tuple`](https://python-all.ru/3.7/library/stdtypes.html#tuple).663- Любому итерируемому объекту, не являющемуся строкой, может быть присвоено *\_\_slots\_\_*. Также могут использоваться отображения; однако в будущем значениям, соответствующим каждому ключу, может быть присвоен особый смысл.664- Присваивание *\_\_class\_\_* работает, только если оба класса имеют одинаковые *\_\_slots\_\_*.665- Множественное наследование с несколькими родительскими классами, имеющими слоты, может использоваться, но только один родитель может иметь атрибуты, созданные слотами (остальные базовые классы должны иметь пустые макеты слотов) – нарушения вызывают [`TypeError`](https://python-all.ru/3.7/library/exceptions.html#TypeError).666- Если для *\_\_slots\_\_* используется итератор, то для каждого значения итератора создаётся дескриптор. Однако атрибут *\_\_slots\_\_* будет пустым итератором.667668### 3.3.3. Настройка создания классов669670Всякий раз, когда класс наследует от другого класса, для этого класса вызывается *\_\_init\_subclass\_\_*. Таким образом можно писать классы, изменяющие поведение подклассов. Это тесно связано с декораторами классов, но если декораторы классов влияют только на тот конкретный класс, к которому они применяются, то `__init_subclass__` применяется исключительно к будущим подклассам класса, определяющего метод.671672#### `classmethod object.__init_subclass__(cls)`673674Этот метод вызывается всякий раз, когда содержащий его класс наследуется. *cls* – это новый подкласс. Если метод определён как обычный метод экземпляра, он неявно преобразуется в метод класса.675676Именованные аргументы, переданные новому классу, передаются в `__init_subclass__` родительского класса. Для совместимости с другими классами, использующими `__init_subclass__`, следует извлечь нужные именованные аргументы, а остальные передать базовому классу, как в примере:677678```python679class Philosopher:680    def __init_subclass__(cls, default_name, **kwargs):681        super().__init_subclass__(**kwargs)682        cls.default_name = default_name683684class AustralianPhilosopher(Philosopher, default_name="Bruce"):685    pass686```687688Реализация по умолчанию `object.__init_subclass__` ничего не делает, но возбуждает ошибку, если вызвана с какими-либо аргументами.689690> **Примечание**691>692> Подсказка метакласса `metaclass` потребляется остальной частью механизма типов и никогда не передаётся в реализации `__init_subclass__`. Фактический метакласс (а не явная подсказка) доступен как `type(cls)`.693694Новое в версии 3.6.695696#### 3.3.3.1. Метаклассы697698По умолчанию классы создаются с помощью [`type()`](https://python-all.ru/3.7/library/functions.html#type). Тело класса выполняется в новом пространстве имён, а имя класса локально привязывается к результату `type(name, bases, namespace)`.699700Процесс создания класса можно настроить, передав `metaclass` ключевой аргумент в строке определения класса или унаследовавшись от существующего класса, который содержит такой аргумент. В следующем примере как `MyClass`, так и `MySubclass` являются экземплярами `Meta`:701702```python703class Meta(type):704    pass705706class MyClass(metaclass=Meta):707    pass708709class MySubclass(MyClass):710    pass711```712713Любые другие ключевые аргументы, указанные в определении класса, передаются всем операциям метакласса, описанным ниже.714715При выполнении определения класса происходят следующие шаги:716717- разрешаются записи MRO;718- определяется подходящий метакласс;719- подготавливается пространство имён класса;720- выполняется тело класса;721- создаётся объект класса.722723#### 3.3.3.2. Разрешение записей MRO724725Если базовый класс, указанный в определении класса, не является экземпляром [`type`](https://python-all.ru/3.7/library/functions.html#type), то на нём ищется метод `__mro_entries__`. Если он найден, он вызывается с исходным кортежем базовых классов. Этот метод должен возвращать кортеж классов, который будет использоваться вместо этого базового класса. Кортеж может быть пустым; в таком случае исходный базовый класс игнорируется.726727> **См. также**728>729> [**PEP 560**](https://python-all.ru/3.7/reference/datamodel.html) – Базовая поддержка модуля typing и обобщённых типов730731#### 3.3.3.3. Определение подходящего метакласса732733Подходящий метакласс для определения класса выбирается следующим образом:734735- если не указаны ни базовые классы, ни явный метакласс, то используется [`type()`](https://python-all.ru/3.7/library/functions.html#type);736- если указан явный метакласс и он *не* является экземпляром [`type()`](https://python-all.ru/3.7/library/functions.html#type), то он используется непосредственно как метакласс;737- если в качестве явного метакласса указан экземпляр [`type()`](https://python-all.ru/3.7/library/functions.html#type), или определены базовые классы, то используется наиболее производный метакласс.738739Наиболее производный метакласс выбирается из явно указанного метакласса (если есть) и метаклассов (т.е. `type(cls)`) всех указанных базовых классов. Наиболее производный метакласс – это такой метакласс, который является подтипом *всех* этих кандидатов. Если ни один из кандидатов не удовлетворяет этому критерию, то определение класса завершится ошибкой `TypeError`.740741#### 3.3.3.4. Подготовка пространства имён класса742743После того как подходящий метакласс определён, подготавливается пространство имён класса. Если у метакласса есть атрибут `__prepare__`, он вызывается как `namespace = metaclass.__prepare__(name, bases, **kwds)` (где дополнительные ключевые аргументы, если таковые имеются, берутся из определения класса). Метод `__prepare__` должен быть реализован как [`classmethod()`](https://python-all.ru/3.7/library/functions.html#classmethod). Пространство имён, возвращённое `__prepare__`, передаётся в `__new__`, но когда окончательный объект класса создаётся, пространство имён копируется в новый `dict`.744745Если у метакласса нет атрибута `__prepare__`, то пространство имён класса инициализируется как пустое упорядоченное отображение.746747> **См. также**748>749> **[**PEP 3115**](https://python-all.ru/3.7/reference/datamodel.html) – Метаклассы в Python 3000**750>751> Ввёл перехватчик пространства имён `__prepare__`752753#### 3.3.3.5. Выполнение тела класса754755Тело класса выполняется (приблизительно) как `exec(body, globals(), namespace)`. Ключевое отличие от обычного вызова [`exec()`](https://python-all.ru/3.7/library/functions.html#exec) заключается в том, что лексическая область видимости позволяет телу класса (включая любые методы) ссылаться на имена из текущей и внешних областей видимости, когда определение класса находится внутри функции.756757Однако, даже если определение класса находится внутри функции, методы, определённые внутри класса, всё равно не видят имена, определённые на уровне класса. Доступ к переменным класса должен осуществляться через первый параметр методов экземпляра или класса, либо через неявную лексически ограниченную ссылку `__class__`, описанную в следующем разделе.758759#### 3.3.3.6. Создание объекта класса760761После заполнения пространства имён класса путём выполнения тела класса объект класса создаётся вызовом `metaclass(name, bases, namespace, **kwds)` (дополнительные ключевые аргументы, переданные здесь, те же, что и переданные в `__prepare__`).762763Этот объект класса – тот самый, на который будет ссылаться форма без аргументов [`super()`](https://python-all.ru/3.7/library/functions.html#super). `__class__` – это неявная ссылка на замыкание, создаваемая компилятором, если какой-либо метод в теле класса обращается к `__class__` или `super`. Благодаря этому форма без аргументов [`super()`](https://python-all.ru/3.7/library/functions.html#super) может корректно определить определяемый класс, исходя из лексической области видимости, а класс или экземпляр, использованный для текущего вызова, определяется по первому аргументу, переданному методу.764765**Особенность реализации CPython:** В CPython 3.6 и новее ячейка `__class__` передаётся метаклассу как запись `__classcell__` в пространстве имён класса. Если она присутствует, она должна быть передана до вызова `type.__new__` для правильной инициализации класса. Несоблюдение этого требования приведёт к [`DeprecationWarning`](https://python-all.ru/3.7/library/exceptions.html#DeprecationWarning) в Python 3.6 и [`RuntimeError`](https://python-all.ru/3.7/library/exceptions.html#RuntimeError) в Python 3.8.766767При использовании метакласса по умолчанию [`type`](https://python-all.ru/3.7/library/functions.html#type) или любого метакласса, который в итоге вызывает `type.__new__`, после создания объекта класса выполняются следующие дополнительные шаги настройки:768769- во-первых, `type.__new__` собирает все дескрипторы в пространстве имён класса, которые определяют метод [`__set_name__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__set_name__);770- во-вторых, все эти методы `__set_name__` вызываются с передачей определяемого класса и присвоенного имени этого конкретного дескриптора;771- наконец, хук [`__init_subclass__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__init_subclass__) вызывается для непосредственного родителя нового класса в порядке разрешения его методов.772773После создания объекта класса он передаётся декораторам класса,\\указанным в определении класса (если они есть), и полученный объект связывается в локальном пространстве имён как определённый класс.774775Когда новый класс создаётся с помощью `type.__new__`, объект, переданный как параметр namespace, копируется в новое упорядоченное отображение, а исходный объект отбрасывается. Новая копия оборачивается в прокси только для чтения,\\который становится атрибутом [`__dict__`](https://python-all.ru/3.7/library/stdtypes.html#object.__dict__) объекта класса.776777> **См. также**778>779> **[**PEP 3135**](https://python-all.ru/3.7/reference/datamodel.html) – Новый super**780>781> Описывает неявную ссылку на замыкание `__class__`782783#### 3.3.3.7. Uses for metaclasses784785Потенциальные применения метаклассов безграничны. Некоторые из изученных идей включают перечисления, логирование, проверку интерфейсов, автоматическое делегирование,\\навтоматическое создание свойств, прокси, фреймворки и автоматическую блокировку/синхронизацию ресурсов.786787### 3.3.4. Customizing instance and subclass checks788789Следующие методы используются для переопределения поведения по умолчанию встроенных функций [`isinstance()`](https://python-all.ru/3.7/library/functions.html#isinstance) и [`issubclass()`](https://python-all.ru/3.7/library/functions.html#issubclass).790791В частности, метакласс [`abc.ABCMeta`](https://python-all.ru/3.7/library/abc.html#abc.ABCMeta) реализует эти методы,\\чтобы позволить добавлять абстрактные базовые классы (ABC) как «виртуальные базовые классы» к любому классу или типу (включая встроенные типы), в том числе к другим ABC.792793#### `class.__instancecheck__(self, instance)`794795Возвращает истину, если *instance* должен считаться (прямым или косвенным) экземпляром *class*. Если определён, вызывается для реализации `isinstance(instance, class)`.796797#### `class.__subclasscheck__(self, subclass)`798799Возвращает истину, если *subclass* должен считаться (прямым или косвенным) подклассом *class*. Если определён, вызывается для реализации `issubclass(subclass, class)`.800801Обратите внимание, что эти методы ищутся на типе (метаклассе) класса. Их нельзя определить как методы класса в самом классе. Это согласуется с поиском специальных методов, которые вызываются на экземплярах, только в данном случае экземпляром является сам класс.802803> **См. также**804>805> **[**PEP 3119**](https://python-all.ru/3.7/reference/datamodel.html) – Введение абстрактных базовых классов**806>807> Содержит спецификацию настройки поведения [`isinstance()`](https://python-all.ru/3.7/library/functions.html#isinstance) и [`issubclass()`](https://python-all.ru/3.7/library/functions.html#issubclass) через [`__instancecheck__()`](https://python-all.ru/3.7/reference/datamodel.html#class.__instancecheck__) и [`__subclasscheck__()`](https://python-all.ru/3.7/reference/datamodel.html#class.__subclasscheck__), с обоснованием этой функциональности в контексте добавления абстрактных базовых классов (см. модуль [`abc`](https://python-all.ru/3.7/library/abc.html#module-abc)) в язык.808809### 3.3.5. Эмуляция обобщённых типов810811Можно реализовать синтаксис обобщённого класса, определённый в [**PEP 484**](https://python-all.ru/3.7/reference/datamodel.html) (например, `List[int]`), определив специальный метод:812813#### `classmethod object.__class_getitem__(cls, key)`814815Возвращает объект, представляющий специализацию обобщённого класса по аргументам типа, переданным в *key*.816817Этот метод ищется на самом объекте класса, и при определении в теле класса он неявно является методом класса. Обратите внимание: этот механизм в первую очередь предназначен для использования со статическими аннотациями типов; другое применение не рекомендуется.818819> **См. также**820>821> [**PEP 560**](https://python-all.ru/3.7/reference/datamodel.html) – Базовая поддержка модуля typing и обобщённых типов822823### 3.3.6. Эмуляция вызываемых объектов824825#### `object.__call__(self[, args...])`826827Вызывается, когда экземпляр «вызывается» как функция; если этот метод определён, `x(arg1, arg2, ...)` является сокращённой формой для `x.__call__(arg1, arg2, ...)`.828829### 3.3.7. Эмуляция контейнерных типов830831Следующие методы могут быть определены для реализации объектов-контейнеров. Контейнеры обычно являются последовательностями (например, списки или кортежи) или отображениями (например, словари), но могут представлять и другие контейнеры. Первый набор методов используется либо для эмуляции последовательности, либо для эмуляции отображения; разница в том, что для последовательности допустимыми ключами должны быть целые числа *k*, для которых `0 <= k < N`, где *N* – длина последовательности, или объекты срезов, определяющие диапазон элементов. Также рекомендуется, чтобы отображения предоставляли методы `keys()`, `values()`, `items()`, `get()`, `clear()`, `setdefault()`, `pop()`, `popitem()`, `copy()`, `update()`, ведущие себя аналогично методам стандартного словаря Python. Модуль [`collections.abc`](https://python-all.ru/3.7/library/collections.abc.html#module-collections.abc) предоставляет абстрактный базовый класс [`MutableMapping`](https://python-all.ru/3.7/library/collections.abc.html#collections.abc.MutableMapping) для создания этих методов из базового набора [`__getitem__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__getitem__), [`__setitem__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__setitem__), [`__delitem__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__delitem__) и `keys()`. Изменяемые последовательности должны предоставлять методы `append()`, `count()`, `index()`, `extend()`, `insert()`, `pop()`, `remove()`, `reverse()` и `sort()`, как стандартные списки Python. Наконец, типы последовательностей должны реализовывать сложение (означающее конкатенацию) и умножение (означающее повторение), определяя методы [`__add__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__add__), [`__radd__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__radd__), [`__iadd__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__iadd__), [`__mul__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__mul__), [`__rmul__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__rmul__) и [`__imul__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__imul__), описанные ниже; они не должны определять другие числовые операторы. Рекомендуется, чтобы и отображения, и последовательности реализовывали метод [`__contains__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__contains__) для эффективного использования оператора `in`; для отображений `in` должен искать в ключах отображения; для последовательностей – в значениях. Также рекомендуется, чтобы и отображения, и последовательности реализовывали метод [`__iter__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__iter__) для эффективного перебора контейнера; для отображений [`__iter__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__iter__) должен перебирать ключи объекта; для последовательностей – значения.832833#### `object.__len__(self)`834835Вызывается для реализации встроенной функции [`len()`](https://python-all.ru/3.7/library/functions.html#len). Должен возвращать длину объекта – целое число `>=` 0. Кроме того, объект, не определяющий метод [`__bool__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__bool__) и чей метод [`__len__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__len__) возвращает ноль, считается ложным в булевом контексте.836837**Особенность реализации CPython:** В CPython длина должна быть не более [`sys.maxsize`](https://python-all.ru/3.7/library/sys.html#sys.maxsize). Если длина больше `sys.maxsize`, некоторые возможности (например, [`len()`](https://python-all.ru/3.7/library/functions.html#len)) могут вызывать [`OverflowError`](https://python-all.ru/3.7/library/exceptions.html#OverflowError). Чтобы предотвратить вызов `OverflowError` при проверке истинности, объект должен определять метод [`__bool__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__bool__).838839#### `object.__length_hint__(self)`840841Вызывается для реализации [`operator.length_hint()`](https://python-all.ru/3.7/library/operator.html#operator.length_hint). Должен возвращать предполагаемую длину объекта (которая может быть больше или меньше фактической длины). Длина должна быть целым числом `>=` 0. Возвращаемое значение также может быть [`NotImplemented`](https://python-all.ru/3.7/library/constants.html#NotImplemented), которое обрабатывается так же, как если бы метод `__length_hint__` вообще не существовал. Этот метод является исключительно оптимизацией и никогда не требуется для корректности.842843Новое в версии 3.4.844845> **Примечание**846>847> Срез выполняется исключительно с помощью следующих трёх методов. Вызов вида848>849> ```python850> a[1:2] = b851> ```852>853> преобразуется в854>855> ```python856> a[slice(1, 2, None)] = b857> ```858>859> и так далее. Отсутствующие элементы среза всегда заполняются значением `None`.860861#### `object.__getitem__(self, key)`862863Вызывается для реализации вычисления `self[key]`. Для последовательностей, допустимыми ключами должны быть целые числа и срезы. Обратите внимание, что особая интерпретация отрицательных индексов (если класс хочет имитировать последовательность типа) возлагается на метод [`__getitem__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__getitem__). Если *key* имеет неподходящий тип, может быть возбуждено [`TypeError`](https://python-all.ru/3.7/library/exceptions.html#TypeError); если значение выходит за пределы множества индексов для последовательности (после любой специальной интерпретации отрицательных значений), следует возбудить [`IndexError`](https://python-all.ru/3.7/library/exceptions.html#IndexError). Для отображений, если *key* отсутствует (не в контейнере), следует возбудить [`KeyError`](https://python-all.ru/3.7/library/exceptions.html#KeyError).864865> **Примечание**866>867> [`for`](https://python-all.ru/3.7/reference/compound_stmts.html#for) ожидают, что для недопустимых индексов будет возбуждено [`IndexError`](https://python-all.ru/3.7/library/exceptions.html#IndexError), чтобы обеспечить правильное обнаружение конца последовательности.868869#### `object.__setitem__(self, key, value)`870871Вызывается для реализации присваивания `self[key]`. То же примечание, что и для [`__getitem__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__getitem__). Этот метод следует реализовывать только для отображений, если объекты поддерживают изменение значений по ключам или добавление новых ключей, или для последовательностей, если элементы можно заменять. Те же исключения должны возбуждаться для неправильных значений *ключа*, что и для метода [`__getitem__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__getitem__).872873#### `object.__delitem__(self, key)`874875Вызывается для реализации удаления `self[key]`. То же примечание, что и для [`__getitem__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__getitem__). Этот метод следует реализовывать только для отображений, если объекты поддерживают удаление ключей, или для последовательностей, если элементы можно удалять из последовательности. Те же исключения должны возбуждаться для неправильных *ключа* значений, что и для метода [`__getitem__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__getitem__).876877#### `object.__missing__(self, key)`878879Вызывается методом [`dict`](https://python-all.ru/3.7/library/stdtypes.html#dict).[`__getitem__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__getitem__) для реализации `self[key]` в подклассах dict, когда ключ отсутствует в словаре.880881#### `object.__iter__(self)`882883Этот метод вызывается, когда для контейнера требуется итератор. Этот метод должен возвращать новый объект-итератор, который может перебирать все объекты в контейнере. Для отображений он должен перебирать ключи контейнера.884885Объекты-итераторы также должны реализовывать этот метод; они обязаны возвращать самих себя. Для получения дополнительной информации об объектах-итераторах см. [Типы итераторов](https://python-all.ru/3.7/library/stdtypes.html#typeiter).886887#### `object.__reversed__(self)`888889Вызывается (если определён) встроенной функцией [`reversed()`](https://python-all.ru/3.7/library/functions.html#reversed) для реализации обратной итерации. Должен возвращать новый объект-итератор, который перебирает все объекты в контейнере в обратном порядке.890891Если метод [`__reversed__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__reversed__) не определён, встроенная функция [`reversed()`](https://python-all.ru/3.7/library/functions.html#reversed) будет использовать протокол последовательности ([`__len__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__len__) и [`__getitem__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__getitem__)). Объекты, поддерживающие протокол последовательности, должны определять [`__reversed__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__reversed__) только в том случае, если могут предоставить реализацию, которая эффективнее, чем предоставленная [`reversed()`](https://python-all.ru/3.7/library/functions.html#reversed).892893Операторы проверки вхождения ([`in`](https://python-all.ru/3.7/reference/expressions.html#in) и [`not in`](https://python-all.ru/3.7/reference/expressions.html#not-in)) обычно реализуются как перебор контейнера. Однако объекты-контейнеры могут предоставить следующий специальный метод с более эффективной реализацией, которая также не требует, чтобы объект был итерируемым.894895#### `object.__contains__(self, item)`896897Вызывается для реализации операторов проверки вхождения. Должен возвращать true, если *элемент* находится в *self*, и false в противном случае. Для объектов-отображений следует учитывать ключи отображения, а не значения или пары ключ-значение.898899Для объектов, которые не определяют [`__contains__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__contains__), проверка вхождения сначала пытается выполнить итерацию через [`__iter__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__iter__), затем старый протокол итерации последовательностей через [`__getitem__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__getitem__); см. [этот раздел в справочнике по языку](https://python-all.ru/3.7/reference/expressions.html#membership-test-details).900901### 3.3.8. Эмуляция числовых типов902903Следующие методы можно определить для эмуляции числовых объектов. Методы, соответствующие операциям, которые не поддерживаются конкретным типом реализуемого числа (например, побитовые операции для нецелых чисел), следует оставить неопределёнными.904905#### `object.__add__(self, other)`906907#### `object.__sub__(self, other)`908909#### `object.__mul__(self, other)`910911#### `object.__matmul__(self, other)`912913#### `object.__truediv__(self, other)`914915#### `object.__floordiv__(self, other)`916917#### `object.__mod__(self, other)`918919#### `object.__divmod__(self, other)`920921#### `object.__pow__(self, other[, modulo])`922923#### `object.__lshift__(self, other)`924925#### `object.__rshift__(self, other)`926927#### `object.__and__(self, other)`928929#### `object.__xor__(self, other)`930931#### `object.__or__(self, other)`932933Эти методы вызываются для реализации бинарных арифметических операций (`+`, `-`, `*`, `@`, `/`, `//`, `%`, [`divmod()`](https://python-all.ru/3.7/library/functions.html#divmod), [`pow()`](https://python-all.ru/3.7/library/functions.html#pow), `**`, `<<`, `>>`, `&`, `^`, `|`). Например, для вычисления выражения `x + y`, где *x* – экземпляр класса, у которого есть метод [`__add__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__add__), вызывается `x.__add__(y)`. Метод [`__divmod__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__divmod__) должен быть эквивалентен использованию [`__floordiv__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__floordiv__) и [`__mod__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__mod__); он не должен быть связан с [`__truediv__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__truediv__). Обратите внимание, что [`__pow__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__pow__) следует определить так, чтобы он принимал необязательный третий аргумент, если требуется поддержка тернарной версии встроенной функции [`pow()`](https://python-all.ru/3.7/library/functions.html#pow).934935Если один из этих методов не поддерживает операцию с переданными аргументами, он должен вернуть `NotImplemented`.936937#### `object.__radd__(self, other)`938939#### `object.__rsub__(self, other)`940941#### `object.__rmul__(self, other)`942943#### `object.__rmatmul__(self, other)`944945#### `object.__rtruediv__(self, other)`946947#### `object.__rfloordiv__(self, other)`948949#### `object.__rmod__(self, other)`950951#### `object.__rdivmod__(self, other)`952953#### `object.__rpow__(self, other[, modulo])`954955#### `object.__rlshift__(self, other)`956957#### `object.__rrshift__(self, other)`958959#### `object.__rand__(self, other)`960961#### `object.__rxor__(self, other)`962963#### `object.__ror__(self, other)`964965Эти методы вызываются для реализации бинарных арифметических операций (`+`, `-`, `*`, `@`, `/`, `//`, `%`, [`divmod()`](https://python-all.ru/3.7/library/functions.html#divmod), [`pow()`](https://python-all.ru/3.7/library/functions.html#pow), `**`, `<<`, `>>`, `&`, `^`, `|`) с отражёнными (переставленными) операндами. Эти функции вызываются только в том случае, если левый операнд не поддерживает соответствующую операцию [3](https://python-all.ru/3.7/reference/datamodel.html#id10) и операнды относятся к разным типам. [4](https://python-all.ru/3.7/reference/datamodel.html#id11) Например, для вычисления выражения `x - y`, где *y* является экземпляром класса, у которого есть метод [`__rsub__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__rsub__), вызывается `y.__rsub__(x)`, если `x.__sub__(y)` возвращает *NotImplemented*.966967Обратите внимание, что тернарная [`pow()`](https://python-all.ru/3.7/library/functions.html#pow) не будет пытаться вызывать [`__rpow__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__rpow__) (правила приведения станут слишком сложными).968969> **Примечание**970>971> Если тип правого операнда является подклассом типа левого операнда и этот подкласс предоставляет отраженный метод для операции, то этот метод будет вызван до неотраженного метода левого операнда. Это поведение позволяет подклассам переопределять операции своих предков.972973#### `object.__iadd__(self, other)`974975#### `object.__isub__(self, other)`976977#### `object.__imul__(self, other)`978979#### `object.__imatmul__(self, other)`980981#### `object.__itruediv__(self, other)`982983#### `object.__ifloordiv__(self, other)`984985#### `object.__imod__(self, other)`986987#### `object.__ipow__(self, other[, modulo])`988989#### `object.__ilshift__(self, other)`990991#### `object.__irshift__(self, other)`992993#### `object.__iand__(self, other)`994995#### `object.__ixor__(self, other)`996997#### `object.__ior__(self, other)`998999Эти методы вызываются для реализации составных арифметических присваиваний (`+=`, `-=`, `*=`, `@=`, `/=`, `//=`, `%=`, `**=`, `<<=`, `>>=`, `&=`, `^=`, `|=`). Эти методы должны пытаться выполнить операцию на месте (изменяя *self*) и возвращать результат (который может быть, но не обязательно, *self*). Если конкретный метод не определён, составное присваивание сводится к обычным методам. Например, если *x* является экземпляром класса с методом [`__iadd__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__iadd__), то `x += y` эквивалентно `x = x.__iadd__(y)`. В противном случае рассматриваются `x.__add__(y)` и `y.__radd__(x)`, как при вычислении `x + y`. В некоторых ситуациях составное присваивание может приводить к неожиданным ошибкам (см. [Почему a\_tuple\[i\] += \['item'\] вызывает исключение, хотя сложение работает?](https://python-all.ru/3.7/faq/programming.html#faq-augmented-assignment-tuple-error)), но такое поведение на самом деле является частью модели данных.10001001#### `object.__neg__(self)`10021003#### `object.__pos__(self)`10041005#### `object.__abs__(self)`10061007#### `object.__invert__(self)`10081009Вызывается для реализации унарных арифметических операций (`-`, `+`, [`abs()`](https://python-all.ru/3.7/library/functions.html#abs) и `~`).10101011#### `object.__complex__(self)`10121013#### `object.__int__(self)`10141015#### `object.__float__(self)`10161017Вызывается для реализации встроенных функций [`complex()`](https://python-all.ru/3.7/library/functions.html#complex), [`int()`](https://python-all.ru/3.7/library/functions.html#int) и [`float()`](https://python-all.ru/3.7/library/functions.html#float). Должен возвращать значение соответствующего типа.10181019#### `object.__index__(self)`10201021Вызывается для реализации [`operator.index()`](https://python-all.ru/3.7/library/operator.html#operator.index), а также всякий раз, когда Python необходимо без потерь преобразовать числовой объект в целое число (например, при срезе или во встроенных функциях [`bin()`](https://python-all.ru/3.7/library/functions.html#bin), [`hex()`](https://python-all.ru/3.7/library/functions.html#hex) и [`oct()`](https://python-all.ru/3.7/library/functions.html#oct)). Наличие этого метода указывает, что числовой объект является целочисленным типом. Должен возвращать целое число.10221023> **Примечание**1024>1025> Чтобы обеспечить целостность класса целочисленного типа, вместе с [`__index__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__index__) следует также определять [`__int__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__int__), и оба метода должны возвращать одно и то же значение.10261027#### `object.__round__(self[, ndigits])`10281029#### `object.__trunc__(self)`10301031#### `object.__floor__(self)`10321033#### `object.__ceil__(self)`10341035Вызывается для реализации встроенной функции [`round()`](https://python-all.ru/3.7/library/functions.html#round) и функций [`math`](https://python-all.ru/3.7/library/math.html#module-math): [`trunc()`](https://python-all.ru/3.7/library/math.html#math.trunc), [`floor()`](https://python-all.ru/3.7/library/math.html#math.floor) и [`ceil()`](https://python-all.ru/3.7/library/math.html#math.ceil). Если *ndigits* не передан в `__round__()`, все эти методы должны возвращать значение объекта, усечённое до [`Integral`](https://python-all.ru/3.7/library/numbers.html#numbers.Integral) (обычно [`int`](https://python-all.ru/3.7/library/functions.html#int)).10361037Если [`__int__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__int__) не определён, то встроенная функция [`int()`](https://python-all.ru/3.7/library/functions.html#int) использует [`__trunc__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__trunc__) в качестве запасного варианта.10381039### 3.3.9. Контекстные менеджеры оператора with10401041*Контекстный менеджер* – это объект, который определяет контекст выполнения, устанавливаемый при выполнении оператора [`with`](https://python-all.ru/3.7/reference/compound_stmts.html#with). Контекстный менеджер обрабатывает вход в требуемый контекст выполнения и выход из него для выполнения блока кода. Контекстные менеджеры обычно вызываются с помощью оператора `with` (описанного в разделе [Оператор with](https://python-all.ru/3.7/reference/compound_stmts.html#with)), но также могут использоваться прямым вызовом их методов.10421043Типичные случаи использования контекстных менеджеров включают сохранение и восстановление различных видов глобального состояния, блокировку и разблокировку ресурсов, закрытие открытых файлов и т.д.10441045Для получения дополнительной информации о контекстных менеджерах см. [Типы контекстных менеджеров](https://python-all.ru/3.7/library/stdtypes.html#typecontextmanager).10461047#### `object.__enter__(self)`10481049Входит в контекст выполнения, связанный с этим объектом. Оператор [`with`](https://python-all.ru/3.7/reference/compound_stmts.html#with) привязывает возвращаемое значение этого метода к цели(ям), указанным в предложении `as` этого оператора, если таковые имеются.10501051#### `object.__exit__(self, exc_type, exc_value, traceback)`10521053Выходит из контекста выполнения, связанного с этим объектом. Параметры описывают исключение, которое привело к выходу из контекста. Если контекст был завершён без исключения, все три аргумента будут [`None`](https://python-all.ru/3.7/library/constants.html#None).10541055Если передано исключение и метод хочет подавить его (т.е. предотвратить его распространение), он должен вернуть истинное значение. В противном случае исключение будет обработано обычным образом при выходе из этого метода.10561057Обратите внимание, что методы [`__exit__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__exit__) не должны повторно возбуждать переданное исключение; это ответственность вызывающего кода.10581059> **См. также**1060>1061> **[**PEP 343**](https://python-all.ru/3.7/reference/datamodel.html) – Оператор «with»**1062>1063> Спецификация, предыстория и примеры для инструкции [`with`](https://python-all.ru/3.7/reference/compound_stmts.html#with) в Python.10641065### 3.3.10. Поиск специальных методов10661067Для пользовательских классов неявные вызовы специальных методов гарантированно работают корректно только в том случае, если они определены в типе объекта, а не в словаре экземпляра объекта. Это поведение является причиной того, что следующий код вызывает исключение:10681069```python1070>>> class C:1071...     pass1072...1073>>> c = C()1074>>> c.__len__ = lambda: 51075>>> len(c)1076Traceback (most recent call last):1077  File "<stdin>", line 1, in <module>1078TypeError: object of type 'C' has no len()1079```10801081Причина такого поведения связана с рядом специальных методов, таких как [`__hash__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__hash__) и [`__repr__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__repr__), которые реализованы во всех объектах, включая объекты типов. Если бы неявный поиск этих методов использовал обычный процесс поиска, они бы завершались неудачей при вызове на самом объекте типа:10821083```python1084>>> 1 .__hash__() == hash(1)1085True1086>>> int.__hash__() == hash(int)1087Traceback (most recent call last):1088  File "<stdin>", line 1, in <module>1089TypeError: descriptor '__hash__' of 'int' object needs an argument1090```10911092Попытка некорректного вызова несвязанного метода класса таким образом иногда называется «путаницей метаклассов»; её можно избежать, обходя экземпляр при поиске специальных методов:10931094```python1095>>> type(1).__hash__(1) == hash(1)1096True1097>>> type(int).__hash__(int) == hash(int)1098True1099```11001101В дополнение к обходу атрибутов экземпляра для обеспечения корректности, неявный поиск специальных методов обычно также обходит метод [`__getattribute__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__getattribute__) даже метакласса объекта:11021103```python1104>>> class Meta(type):1105...     def __getattribute__(*args):1106...         print("Metaclass getattribute invoked")1107...         return type.__getattribute__(*args)1108...1109>>> class C(object, metaclass=Meta):1110...     def __len__(self):1111...         return 101112...     def __getattribute__(*args):1113...         print("Class getattribute invoked")1114...         return object.__getattribute__(*args)1115...1116>>> c = C()1117>>> c.__len__()                 # Явный поиск через экземпляр1118Class getattribute invoked1119101120>>> type(c).__len__(c)          # Явный поиск через тип1121Metaclass getattribute invoked1122101123>>> len(c)                      # Неявный поиск1124101125```11261127Обход механизма [`__getattribute__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__getattribute__) таким образом даёт значительную возможность для оптимизации скорости в интерпретаторе, ценой некоторой гибкости в обработке специальных методов (специальный метод *должен* быть установлен на самом объекте класса, чтобы интерпретатор мог его последовательно вызывать).11281129## 3.4. Корутины11301131### 3.4.1. Ожидаемые объекты11321133Объект [ожидаемый объект](https://python-all.ru/3.7/glossary.html#term-awaitable) обычно реализует метод [`__await__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__await__). Объекты [корутина](https://python-all.ru/3.7/glossary.html#term-coroutine), возвращаемые функциями [`async def`](https://python-all.ru/3.7/reference/compound_stmts.html#async-def), являются ожидаемыми.11341135> **Примечание**1136>1137> Объекты [итератора генератора](https://python-all.ru/3.7/glossary.html#term-generator-iterator), возвращаемые из генераторов, декорированных с помощью [`types.coroutine()`](https://python-all.ru/3.7/library/types.html#types.coroutine) или [`asyncio.coroutine()`](https://python-all.ru/3.7/library/asyncio-task.html#asyncio.coroutine), также являются ожидаемыми, но не реализуют [`__await__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__await__).11381139#### `object.__await__(self)`11401141Должен возвращать [итератор](https://python-all.ru/3.7/glossary.html#term-iterator). Следует использовать для реализации объектов [ожидаемых](https://python-all.ru/3.7/glossary.html#term-awaitable). Например, [`asyncio.Future`](https://python-all.ru/3.7/library/asyncio-future.html#asyncio.Future) реализует этот метод для совместимости с выражением [`await`](https://python-all.ru/3.7/reference/expressions.html#await).11421143Новое в версии 3.5.11441145> **См. также**1146>1147> [**PEP 492**](https://python-all.ru/3.7/reference/datamodel.html) для получения дополнительной информации об ожидаемых объектах.11481149### 3.4.2. Объекты корутин11501151Объекты [корутина](https://python-all.ru/3.7/glossary.html#term-coroutine) являются объектами [ожидаемый](https://python-all.ru/3.7/glossary.html#term-awaitable). Выполнение корутины можно контролировать, вызывая [`__await__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__await__) и итерируя результат. Когда корутина завершает выполнение и возвращает значение, итератор возбуждает [`StopIteration`](https://python-all.ru/3.7/library/exceptions.html#StopIteration), а атрибут `value` исключения содержит возвращаемое значение. Если корутина возбуждает исключение, оно распространяется итератором. Корутины не должны напрямую возбуждать необработанные исключения [`StopIteration`](https://python-all.ru/3.7/library/exceptions.html#StopIteration).11521153Корутины также имеют методы, перечисленные ниже, которые аналогичны методам генераторов (см. [Методы итератора генератора](https://python-all.ru/3.7/reference/expressions.html#generator-methods)). Однако, в отличие от генераторов, корутины напрямую не поддерживают итерацию.11541155Изменено в версии 3.5.2: Ожидание корутины более одного раза является [`RuntimeError`](https://python-all.ru/3.7/library/exceptions.html#RuntimeError).11561157#### `coroutine.send(value)`11581159Запускает или возобновляет выполнение корутины. Если *value* равно `None`, это эквивалентно продвижению итератора, возвращаемого [`__await__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__await__). Если *value* не равно `None`, этот метод делегирует методу [`send()`](https://python-all.ru/3.7/reference/expressions.html#generator.send) итератора, который вызвал приостановку корутины. Результат (возвращаемое значение, [`StopIteration`](https://python-all.ru/3.7/library/exceptions.html#StopIteration) или другое исключение) такой же, как при итерации по возвращаемому значению [`__await__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__await__), описанной выше.11601161#### `coroutine.throw(type[, value[, traceback]])`11621163Возбуждает указанное исключение в корутине. Этот метод делегирует методу [`throw()`](https://python-all.ru/3.7/reference/expressions.html#generator.throw) итератора, который вызвал приостановку корутины, если у него есть такой метод. В противном случае исключение возбуждается в точке приостановки. Результат (возвращаемое значение, [`StopIteration`](https://python-all.ru/3.7/library/exceptions.html#StopIteration) или другое исключение) такой же, как при итерации по возвращаемому значению [`__await__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__await__), описанной выше. Если исключение не перехвачено в корутине, оно распространяется обратно к вызывающему.11641165#### `coroutine.close()`11661167Заставляет корутину выполнить очистку и завершиться. Если корутина приостановлена, этот метод сначала делегирует методу [`close()`](https://python-all.ru/3.7/reference/expressions.html#generator.close) итератора, который вызвал приостановку корутины, если у него есть такой метод. Затем он возбуждает [`GeneratorExit`](https://python-all.ru/3.7/library/exceptions.html#GeneratorExit) в точке приостановки, заставляя корутину немедленно выполнить очистку. Наконец, корутина помечается как завершившая выполнение, даже если она никогда не была запущена.11681169Объекты корутин автоматически закрываются с помощью описанного выше процесса, когда они собираются быть уничтоженными.11701171### 3.4.3. Асинхронные итераторы11721173Объект *асинхронный итератор* может вызывать асинхронный код в своем методе `__anext__`.11741175Асинхронные итераторы можно использовать в операторе [`async for`](https://python-all.ru/3.7/reference/compound_stmts.html#async-for).11761177#### `object.__aiter__(self)`11781179Должен возвращать объект *асинхронный итератор*.11801181#### `object.__anext__(self)`11821183Должен возвращать *ожидаемый объект*, который даёт следующее значение итератора. Должен возбуждать ошибку [`StopAsyncIteration`](https://python-all.ru/3.7/library/exceptions.html#StopAsyncIteration), когда итерация завершена.11841185Пример асинхронного итерируемого объекта:11861187```python1188class Reader:1189    async def readline(self):1190        ...11911192    def __aiter__(self):1193        return self11941195    async def __anext__(self):1196        val = await self.readline()1197        if val == b'':1198            raise StopAsyncIteration1199        return val1200```12011202Новое в версии 3.5.12031204Изменено в версии 3.7: До Python 3.7 `__aiter__` мог возвращать *ожидаемый объект*, который разрешался в [асинхронный итератор](https://python-all.ru/3.7/glossary.html#term-asynchronous-iterator).12051206Начиная с Python 3.7, `__aiter__` должен возвращать объект асинхронного итератора. Возврат чего-либо ещё приводит к ошибке [`TypeError`](https://python-all.ru/3.7/library/exceptions.html#TypeError).12071208### 3.4.4. Асинхронные менеджеры контекста12091210*Асинхронный менеджер контекста* – это *менеджер контекста*, способный приостанавливать выполнение в своих методах `__aenter__` и `__aexit__`.12111212Асинхронные менеджеры контекста можно использовать в инструкции [`async with`](https://python-all.ru/3.7/reference/compound_stmts.html#async-with).12131214#### `object.__aenter__(self)`12151216Этот метод семантически похож на [`__enter__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__enter__), с той лишь разницей, что он должен возвращать *ожидаемый объект*.12171218#### `object.__aexit__(self, exc_type, exc_value, traceback)`12191220Этот метод семантически похож на [`__exit__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__exit__), с той лишь разницей, что он должен возвращать *ожидаемый объект*.12211222Пример класса асинхронного менеджера контекста:12231224```python1225class AsyncContextManager:1226    async def __aenter__(self):1227        await log('entering context')12281229    async def __aexit__(self, exc_type, exc, tb):1230        await log('exiting context')1231```12321233Новое в версии 3.5.12341235Сноски12361237**[1](https://python-all.ru/3.7/reference/datamodel.html#id1)**12381239It *is* possible in some cases to change an object’s type, under certain controlled conditions. It generally isn’t a good idea though, since it can lead to some very strange behaviour if it is handled incorrectly.12401241**[2](https://python-all.ru/3.7/reference/datamodel.html#id2)**12421243Методы [`__hash__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__hash__), [`__iter__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__iter__), [`__reversed__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__reversed__) и [`__contains__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__contains__) имеют специальную обработку для этого; остальные всё равно вызовут [`TypeError`](https://python-all.ru/3.7/library/exceptions.html#TypeError), но могут сделать это, полагаясь на то, что `None` не является вызываемым.12441245**[3](https://python-all.ru/3.7/reference/datamodel.html#id5)**12461247«Не поддерживает» здесь означает, что у класса нет такого метода или метод возвращает `NotImplemented`. Не устанавливайте метод в `None`, если хотите принудительно вернуться к отражённому методу правого операнда – это даст противоположный эффект, явно *блокируя* такой возврат.12481249**[4](https://python-all.ru/3.7/reference/datamodel.html#id6)**12501251Для операндов одного типа предполагается, что если неотражённый метод (например, [`__add__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__add__)) завершается неудачей, операция не поддерживается, поэтому отражённый метод не вызывается.1252