3. Модель данных

3.1. Объекты, значения и типы

Objects - это абстракция Python для данных. Все данные в программе на Python представлены объектами или отношениями между объектами. (В некотором смысле, в соответствии с моделью фон Неймана о «компьютере с хранимыми программами», код также представлен объектами).

У каждого объекта есть идентификатор, тип и значение. Идентичность объекта никогда не меняется после его создания; вы можете считать ее адресом объекта в памяти. Оператор is сравнивает идентичность двух объектов; функция id() возвращает целое число, представляющее его идентичность.

Детали реализации CPython: Для CPython id(x) - это адрес памяти, в которой хранится x.

Тип объекта определяет операции, которые он поддерживает (например, «имеет ли он длину?»), а также определяет возможные значения для объектов этого типа. Функция type() возвращает тип объекта (который сам является объектом). Как и его идентичность, type объекта также неизменна. [1]

Значение некоторых объектов может меняться. Объекты, значение которых может изменяться, называются изменяемыми; объекты, значение которых не изменяется после их создания, называются неизменяемыми. (Значение неизменяемого объекта-контейнера, содержащего ссылку на мутабельный объект, может измениться при изменении значения последнего; однако контейнер все равно считается неизменяемым, поскольку коллекция объектов, которую он содержит, не может быть изменена. Таким образом, неизменяемость - это не совсем то же самое, что неизменяемое значение, это более тонкий момент). Мутабельность объекта определяется его типом; например, числа, строки и кортежи являются неизменяемыми, а словари и списки - мутабельными.

Объекты никогда не уничтожаются явно; однако, когда они становятся недоступными, они могут быть собраны в мусор. Реализация может отложить сборку мусора или вовсе отказаться от нее - это вопрос качества реализации, как будет реализована сборка мусора, если не будут собраны объекты, до которых еще можно добраться.

Детали реализации CPython: В настоящее время CPython использует схему подсчета ссылок с (необязательным) отложенным обнаружением циклически связанного мусора, которая собирает большинство объектов, как только они становятся недостижимыми, но не гарантирует сбор мусора, содержащего циклические ссылки. Информацию об управлении сбором циклического мусора см. в документации к модулю gc. Другие реализации действуют иначе, и CPython может измениться. Не полагайтесь на немедленную финализацию объектов, когда они становятся недоступными (поэтому всегда закрывайте файлы явно).

Обратите внимание, что использование средств трассировки или отладки реализации может оставить в живых объекты, которые обычно можно было бы собрать. Также обратите внимание, что перехват исключения с помощью оператора tryexcept может сохранить объекты живыми.

Некоторые объекты содержат ссылки на «внешние» ресурсы, такие как открытые файлы или окна. Подразумевается, что эти ресурсы освобождаются при сборке мусора, но поскольку сборка мусора не гарантирована, такие объекты также предоставляют явный способ освобождения внешнего ресурса, обычно метод close(). Программам настоятельно рекомендуется явно закрывать такие объекты. Утверждение tryfinally и утверждение with предоставляют удобные способы сделать это.

Некоторые объекты содержат ссылки на другие объекты; они называются контейнерами. Примерами контейнеров являются кортежи, списки и словари. Ссылки являются частью значения контейнера. В большинстве случаев, когда мы говорим о значении контейнера, мы подразумеваем значения, а не идентификаторы содержащихся в нем объектов; однако, когда мы говорим о изменяемости контейнера, подразумеваются только идентификаторы непосредственно содержащихся в нем объектов. Так, если неизменяемый контейнер (например, кортеж) содержит ссылку на изменяемый объект, его значение изменится при изменении этого изменяемого объекта.

Типы влияют практически на все аспекты поведения объектов. Даже важность идентичности объектов в некотором смысле затрагивается: для неизменяемых типов операции, вычисляющие новые значения, могут фактически возвращать ссылку на любой существующий объект с тем же типом и значением, в то время как для изменяемых объектов это недопустимо. Например, после a = 1; b = 1, a и b могут ссылаться или не ссылаться на один и тот же объект со значением one, в зависимости от реализации, но после c = []; d = [], c и d гарантированно ссылаются на два разных, уникальных, вновь созданных пустых списка. (Обратите внимание, что c = d = [] присваивает один и тот же объект и c, и d).

3.2. Стандартная иерархия типов

Ниже приведен список типов, встроенных в Python. Модули расширения (написанные на C, Java или других языках, в зависимости от реализации) могут определять дополнительные типы. Будущие версии Python могут добавить типы в иерархию типов (например, рациональные числа, эффективно хранимые массивы целых чисел и т. д.), хотя такие дополнения часто будут предоставляться через стандартную библиотеку.

Некоторые из приведенных ниже описаний типов содержат параграф, в котором перечислены «специальные атрибуты». Это атрибуты, которые предоставляют доступ к реализации и не предназначены для общего использования. Их определение может измениться в будущем.

3.2.1. Нет

Этот тип имеет единственное значение. Существует единственный объект с этим значением. Доступ к этому объекту осуществляется через встроенное имя None. Он используется для обозначения отсутствия значения во многих ситуациях, например, возвращается из функций, которые явно ничего не возвращают. Его истинностное значение - false.

3.2.2. NotImplemented

Этот тип имеет единственное значение. Существует единственный объект с этим значением. Доступ к этому объекту осуществляется через встроенное имя NotImplemented. Числовые методы и методы сравнения должны возвращать это значение, если они не реализуют операцию для предоставленных операндов. (Тогда интерпретатор попробует отраженную операцию или другой запасной вариант, в зависимости от оператора). Это значение не должно оцениваться в контексте булевых значений.

Более подробную информацию см. в разделе Реализация арифметических операций.

Изменено в версии 3.9: Оценка NotImplemented в булевом контексте была устаревшей.

Изменено в версии 3.14: Оценка NotImplemented в булевом контексте теперь выводит TypeError. Ранее, начиная с Python 3.9, она оценивалась в True и выдавала DeprecationWarning.

3.2.3. Эллипсис

Этот тип имеет единственное значение. Существует единственный объект с этим значением. Доступ к этому объекту осуществляется через литерал ... или встроенное имя Ellipsis. Его истинностное значение - true.

3.2.4. numbers.Number

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

Строковые представления числовых классов, вычисляемые через __repr__() и __str__(), обладают следующими свойствами:

  • Они представляют собой допустимые числовые литералы, которые при передаче в конструктор своего класса создают объект, имеющий значение исходного числа.

  • По возможности, представление ведется по основанию 10.

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

  • Нули в конце строки, возможно, за исключением одного нуля после десятичной точки, не отображаются.

  • Знак ставится только в том случае, если число отрицательное.

Python различает целые числа, числа с плавающей точкой и комплексные числа:

3.2.4.1. numbers.Integral

Они представляют собой элементы из математического набора целых чисел (положительных и отрицательных).

Примечание

Правила представления целых чисел предназначены для наиболее осмысленной интерпретации операций сдвига и маскирования отрицательных целых чисел.

Существует два типа целых чисел:

Целые числа (int)

Они представляют числа в неограниченном диапазоне, ограниченные только доступной (виртуальной) памятью. Для операций сдвига и маскирования предполагается двоичное представление, а отрицательные числа представляются в варианте 2’s complement, который создает иллюзию бесконечной строки знаковых битов, простирающейся влево.

Булевы (bool)

Они представляют истинностные значения False и True. Два объекта, представляющие значения False и True, являются единственными булевыми объектами. Тип Boolean является подтипом типа integer, и булевы значения ведут себя как значения 0 и 1, соответственно, почти во всех контекстах, за исключением того, что при преобразовании в строку возвращаются строки "False" или "True", соответственно.

3.2.4.2. numbers.Real (float)

Они представляют собой числа с плавающей точкой двойной точности машинного уровня. Принятый диапазон и обработка переполнения зависят от архитектуры машины (и реализации на C или Java). Python не поддерживает числа с плавающей запятой одинарной точности; экономия процессора и памяти, которая обычно является причиной использования этих чисел, перекрывается накладными расходами на использование объектов в Python, поэтому нет смысла усложнять язык двумя видами чисел с плавающей запятой.

3.2.4.3. numbers.Complex (complex)

Они представляют комплексные числа в виде пары машинных чисел двойной точности с плавающей точкой. Здесь действуют те же предостережения, что и для чисел с плавающей точкой. Действительная и мнимая части комплексного числа z могут быть получены через атрибуты z.real и z.imag, доступные только для чтения.

3.2.5. Последовательности

Они представляют собой конечные упорядоченные множества, индексируемые неотрицательными числами. Встроенная функция len() возвращает количество элементов последовательности. Если длина последовательности равна n, то индексное множество содержит числа 0, 1, …, n-1. Элемент i последовательности a выбирается по a[i]. Некоторые последовательности, в том числе встроенные, интерпретируют отрицательные подписи путем добавления длины последовательности. Например, a[-2] равно a[n-2], предпоследнему элементу последовательности a длиной n.

Последовательности также поддерживают нарезку: a[i:j] выбирает все элементы с индексом k такие, что i <= k < j. При использовании в качестве выражения срез - это последовательность того же типа. Замечание выше об отрицательных индексах также относится к отрицательным позициям срезов.

Некоторые последовательности также поддерживают «расширенную нарезку» с третьим параметром «шаг»: a[i:j:k] выбирает все элементы a с индексом x, где x = i + n*k, n >= 0 и i <= x < j.

Последовательности различаются в зависимости от их изменяемости:

3.2.5.1. Неизменяемые последовательности

Объект неизменяемого типа последовательности не может измениться после его создания. (Если объект содержит ссылки на другие объекты, эти другие объекты могут быть мутабельными и могут быть изменены; однако коллекция объектов, на которые непосредственно ссылается неизменяемый объект, не может измениться).

Следующие типы являются неизменяемыми последовательностями:

Струны

Строка - это последовательность значений, представляющих кодовые точки Unicode. Все кодовые точки в диапазоне U+0000 - U+10FFFF могут быть представлены в строке. В Python нет типа char; вместо этого каждая кодовая точка в строке представляется как строковый объект длиной 1. Встроенная функция ord() преобразует кодовую точку из ее строковой формы в целое число в диапазоне 0 - 10FFFF; chr() преобразует целое число в диапазоне 0 - 10FFFF в строковый объект соответствующей длины 1. str.encode() может использоваться для преобразования str в bytes с использованием заданной текстовой кодировки, а bytes.decode() - для достижения обратного результата.

Кортежи

Элементы кортежа - это произвольные объекты Python. Кортежи из двух или более элементов формируются из списков выражений, разделенных запятыми. Кортеж из одного элемента («синглтон») может быть сформирован путем присоединения запятой к выражению (выражение само по себе не создает кортеж, поскольку скобки должны использоваться для группировки выражений). Пустой кортеж может быть образован пустой парой круглых скобок.

Байты

Объект bytes - это неизменяемый массив. Элементами являются 8-битные байты, представленные целыми числами в диапазоне 0 <= x < 256. Для создания байтовых объектов можно использовать литералы байтов (например, b'abc') и встроенный конструктор bytes(). Кроме того, объекты bytes можно декодировать в строки с помощью метода decode().

3.2.5.2. Мутирующие последовательности

Изменчивые последовательности могут быть изменены после их создания. Нотации подписки и нарезки могут использоваться в качестве цели операторов присваивания и del (удаления).

Примечание

Модуль collections и array представляют собой дополнительные примеры изменяемых типов последовательностей.

В настоящее время существует два внутренних изменяемых типа последовательностей:

Списки

Элементы списка - это произвольные объекты Python. Списки формируются путем помещения списка выражений, разделенных запятыми, в квадратные скобки. (Обратите внимание, что для формирования списков длиной 0 или 1 не требуется никаких специальных случаев).

Массивы байтов

Объект bytearray - это изменяемый массив. Они создаются с помощью встроенного конструктора bytearray(). Помимо того, что байтовые массивы являются мутабельными (и, следовательно, нехешируемыми), в остальном они предоставляют тот же интерфейс и функциональность, что и неизменяемые объекты bytes.

3.2.6. Типы наборов

Они представляют собой неупорядоченные, конечные наборы уникальных, неизменяемых объектов. Как таковые, они не могут быть проиндексированы никаким подскриптом. Однако их можно итерировать, а встроенная функция len() возвращает количество элементов в наборе. Обычно множества используются для быстрой проверки принадлежности, удаления дубликатов из последовательности и вычисления математических операций, таких как пересечение, объединение, разность и симметричная разность.

Для элементов множества действуют те же правила неизменяемости, что и для ключей словаря. Обратите внимание, что числовые типы подчиняются обычным правилам числового сравнения: если два числа сравниваются одинаково (например, 1 и 1.0), только одно из них может содержаться в наборе.

В настоящее время существует два типа встроенных наборов:

Наборы

Они представляют собой изменяемое множество. Они создаются встроенным конструктором set() и могут быть изменены впоследствии несколькими методами, например add().

Замороженные декорации

Они представляют собой неизменяемое множество. Они создаются с помощью встроенного конструктора frozenset(). Поскольку фростенсет неизменяем и hashable, он может быть использован как элемент другого множества или как ключ словаря.

3.2.7. Отображения

Они представляют собой конечные наборы объектов, индексируемых произвольными наборами индексов. Условное обозначение a[k] выбирает из отображения a элемент, индексируемый k; его можно использовать в выражениях и в качестве цели присваиваний или операторов del. Встроенная функция len() возвращает количество элементов в отображении.

В настоящее время существует единственный тип отображения:

3.2.7.1. Словари

Они представляют собой конечные наборы объектов, индексируемых практически произвольными значениями. Единственные типы значений, которые недопустимы в качестве ключей, - это значения, содержащие списки, словари или другие изменяемые типы, которые сравниваются по значению, а не по идентичности объекта; причина в том, что эффективная реализация словарей требует, чтобы хэш-значение ключа оставалось постоянным. Числовые типы, используемые для ключей, подчиняются обычным правилам числового сравнения: если два числа сравниваются одинаково (например, 1 и 1.0), то они могут быть использованы для индексации одной и той же словарной статьи.

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

Словари являются изменяемыми; они могут быть созданы с помощью нотации {...} (см. раздел Словарные дисплеи).

Модули расширения dbm.ndbm и dbm.gnu предоставляют дополнительные примеры типов отображения, как и модуль collections.

Изменено в версии 3.7: Словари не сохраняли порядок вставки в версиях Python до 3.6. В CPython 3.6 порядок вставки был сохранен, но в то время это считалось деталью реализации, а не языковой гарантией.

3.2.8. Вызываемые типы

Это типы, к которым может быть применена операция вызова функции (см. раздел Звонки):

3.2.8.1. Определяемые пользователем функции

Объект пользовательской функции создается определением функции (см. раздел Определения функций). Он должен вызываться со списком аргументов, содержащим то же количество элементов, что и список формальных параметров функции.

3.2.8.1.1. Специальные атрибуты, доступные только для чтения

Атрибут

Значение

function.__globals__

Ссылка на dictionary, в котором хранится global variables функции. – глобальное пространство имен модуля, в котором была определена функция.

function.__closure__

None или tuple ячеек, содержащих привязки для свободных переменных функции.

Объект ячейки имеет атрибут cell_contents. С его помощью можно получить значение ячейки, а также установить его.

3.2.8.1.2. Специальные атрибуты, доступные для записи

Большинство этих атрибутов проверяют тип присвоенного значения:

Атрибут

Значение

function.__doc__

Строка документации функции, или None, если она недоступна. Не наследуется подклассами.

function.__name__

Имя функции. См. также: __name__ attributes.

function.__qualname__

Функция qualified name. См. также: __qualname__ attributes.

Added in version 3.3.

function.__module__

Имя модуля, в котором была определена функция, или None, если он недоступен.

function.__defaults__

Значение tuple, содержащее значения по умолчанию parameter для тех параметров, которые имеют значения по умолчанию, или None, если ни один параметр не имеет значения по умолчанию.

function.__code__

code object, представляющий скомпилированное тело функции.

function.__dict__

Пространство имен, поддерживающее произвольные атрибуты функций. См. также: __dict__ attributes.

function.__annotations__

Словарь dictionary, содержащий аннотации parameters. Ключами словаря являются имена параметров, а 'return' - аннотация возврата, если она предусмотрена. См. также: Лучшие практики использования аннотаций.

function.__kwdefaults__

dictionary, содержащий значения по умолчанию для ключевых слов только parameters.

function.__type_params__

tuple, содержащий type parameters из generic function.

Added in version 3.12.

Объекты функций также поддерживают получение и установку произвольных атрибутов, которые могут быть использованы, например, для прикрепления метаданных к функциям. Для получения и установки таких атрибутов используется обычная атрибутивная точка-нотация.

Детали реализации CPython: Текущая реализация CPython поддерживает атрибуты функций только для функций, определяемых пользователем. Атрибуты функций для built-in functions могут быть поддержаны в будущем.

Дополнительная информация об определении функции может быть получена из ее code object (доступной через атрибут __code__).

3.2.8.2. Методы экземпляра

Объект метода экземпляра объединяет класс, экземпляр класса и любой вызываемый объект (обычно пользовательскую функцию).

Специальные атрибуты, доступные только для чтения:

method.__self__

Указывает на объект экземпляра класса, к которому применяется метод bound.

method.__func__

Относится к исходному function object.

method.__doc__

Документация метода (такая же, как method.__func__.__doc__). Указывается string, если исходная функция имела документированную строку, иначе None.

method.__name__

Имя метода (такое же, как method.__func__.__name__)

method.__module__

Имя модуля, в котором был определен метод, или None, если он недоступен.

Методы также поддерживают доступ (но не установку) к атрибутам произвольной функции на базовом function object.

Определенные пользователем объекты методов могут быть созданы при получении атрибута класса (возможно, через экземпляр этого класса), если этот атрибут является определенным пользователем объектом function object или classmethod.

Когда объект метода экземпляра создается путем извлечения определенного пользователем function object из класса через один из его экземпляров, его атрибутом __self__ является экземпляр, а объект метода, как говорят, связан. Атрибутом __func__ нового метода является исходный объект функции.

Когда объект метода экземпляра создается путем извлечения объекта classmethod из класса или экземпляра, его атрибутом __self__ является сам класс, а атрибутом __func__ - объект функции, лежащий в основе метода класса.

Когда вызывается объект метода экземпляра, вызывается базовая функция (__func__), вставляя экземпляр класса (__self__) перед списком аргументов. Например, если C - класс, содержащий определение функции f(), а x - экземпляр C, вызов x.f(1) эквивалентен вызову C.f(x, 1).

Когда объект метода экземпляра является производным от объекта classmethod, «экземпляр класса», хранящийся в __self__, на самом деле является самим классом, так что вызов x.f(1) или C.f(1) эквивалентен вызову f(C,1), где f является базовой функцией.

Обратите внимание, что преобразование из function object в объект метода экземпляра происходит каждый раз, когда атрибут извлекается из экземпляра. В некоторых случаях полезной оптимизацией является присвоение атрибута локальной переменной и вызов этой локальной переменной. Также обратите внимание, что это преобразование происходит только для пользовательских функций; другие вызываемые объекты (и все невызываемые объекты) извлекаются без преобразования. Также важно отметить, что пользовательские функции, являющиеся атрибутами экземпляра класса, не преобразуются в связанные методы; это происходит только в том случае, если функция является атрибутом класса.

3.2.8.3. Функции генератора

Функция или метод, использующие оператор yield (см. раздел Заявление yield), называются generator function. Такая функция при вызове всегда возвращает объект iterator, который может быть использован для выполнения тела функции: вызов метода iterator.__next__() итератора заставит функцию выполняться до тех пор, пока она не получит значение с помощью оператора yield. Когда функция выполнит оператор return или свалится в конец, возникнет исключение StopIteration, а итератор достигнет конца набора возвращаемых значений.

3.2.8.4. Корутинные функции

Функция или метод, заданные с помощью async def, называются coroutine function. Такая функция при вызове возвращает объект coroutine. Она может содержать выражения await, а также операторы async with и async for. См. также раздел Объекты корутины.

3.2.8.5. Функции асинхронного генератора

Функция или метод, заданные с помощью async def и использующие оператор yield, называются asynchronous generator function. Такая функция при вызове возвращает объект asynchronous iterator, который может быть использован в операторе async for для выполнения тела функции.

Вызов метода aiterator.__anext__ асинхронного итератора вернет awaitable, который в ожидании будет выполняться до тех пор, пока не будет получено значение с помощью выражения yield. Если функция выполнит пустое выражение return или не дойдет до конца, будет вызвано исключение StopAsyncIteration, а асинхронный итератор достигнет конца набора значений, которые должны быть выданы.

3.2.8.6. Встроенные функции

Объект встроенной функции - это обертка вокруг функции языка Си. Примерами встроенных функций являются len() и math.sin() (math - стандартный встроенный модуль). Количество и тип аргументов определяются функцией C. Специальные атрибуты, доступные только для чтения:

  • __doc__ - строка документации функции, или None, если она недоступна. См. function.__doc__.

  • __name__ - это имя функции. См. function.__name__.

  • Для __self__ установлено значение None (но см. следующий пункт).

  • __module__ - имя модуля, в котором была определена функция, или None, если он недоступен. См. function.__module__.

3.2.8.7. Встроенные методы

На самом деле это другая маскировка встроенной функции, на этот раз содержащая объект, передаваемый в функцию C в качестве неявного дополнительного аргумента. Примером встроенного метода является alist.append(), предполагающий, что alist - это объект списка. В этом случае для объекта, обозначенного alist, устанавливается специальный атрибут __self__, доступный только для чтения. (Атрибут имеет ту же семантику, что и в случае с other instance methods).

3.2.8.8. Занятия

Классы являются вызываемыми. Обычно эти объекты выступают в роли фабрик для новых экземпляров самих себя, но возможны вариации для типов классов, переопределяющих __new__(). Аргументы вызова передаются в __new__() и, в типичном случае, в __init__() для инициализации нового экземпляра.

3.2.8.9. Экземпляры классов

Экземпляры произвольных классов можно сделать вызываемыми, определив в их классе метод __call__().

3.2.9. Модули

Модули являются основной организационной единицей кода Python и создаются с помощью оператора import system, вызываемого либо оператором import, либо путем вызова функций, таких как importlib.import_module() и встроенные __import__(). Объект модуля имеет пространство имен, реализуемое объектом dictionary (это словарь, на который ссылается атрибут __globals__ функций, определенных в модуле). Ссылки на атрибуты переводятся в поиск в этом словаре, например, m.x эквивалентен m.__dict__["x"]. Объект модуля не содержит объект кода, используемый для инициализации модуля (поскольку после инициализации он не нужен).

Присвоение атрибутов обновляет словарь пространств имен модуля, например, m.x = 1 эквивалентно m.__dict__["x"] = 1.

Предопределенные (записываемые) атрибуты:

__name__

Имя модуля.

__doc__

Строка документации модуля, или None, если она недоступна.

__file__

Имя пути к файлу, из которого был загружен модуль, если он был загружен из файла. Атрибут __file__ может отсутствовать для некоторых типов модулей, например модулей на языке C, статически подключаемых к интерпретатору. Для модулей расширения, загружаемых динамически из общей библиотеки, это имя пути к файлу общей библиотеки.

__annotations__

Словарь, содержащий variable annotations, собранные во время выполнения тела модуля. О лучших практиках работы с __annotations__ читайте в разделе Лучшие практики использования аннотаций.

Специальный атрибут, доступный только для чтения: __dict__ - пространство имен модуля в виде словарного объекта.

Детали реализации CPython: Из-за того, как CPython очищает словари модулей, словарь модуля будет очищен, когда модуль выйдет из области видимости, даже если в словаре останутся живые ссылки. Чтобы избежать этого, скопируйте словарь или держите модуль рядом, используя его словарь напрямую.

3.2.10. Пользовательские классы

Пользовательские типы классов обычно создаются в определениях классов (см. раздел Определения классов). Класс имеет пространство имен, реализованное в виде объекта-словаря. Ссылки на атрибуты класса переводятся в поиск в этом словаре, например, C.x переводится в C.__dict__["x"] (хотя существует ряд крючков, позволяющих использовать другие способы поиска атрибутов). Если имя атрибута не найдено, поиск атрибута продолжается в базовых классах. Этот поиск в базовых классах использует порядок разрешения методов C3, который ведет себя корректно даже при наличии «ромбовидных» структур наследования, когда существует несколько путей наследования, ведущих к общему предку. Дополнительные подробности о C3 MRO, используемом в Python, можно найти в Порядок разрешения методов в Python 2.3.

Когда ссылка на атрибут класса (скажем, для класса C) дает объект метода класса, она преобразуется в объект метода экземпляра, атрибутом __self__ которого является C. Если в результате будет получен объект staticmethod, он преобразуется в объект, обернутый статическим объектом метода. Еще один способ, с помощью которого атрибуты, получаемые из класса, могут отличаться от тех, которые на самом деле содержатся в его __dict__, см. в разделе Реализация дескрипторов.

Назначения атрибутов класса обновляют словарь класса, но не словарь базового класса.

Объект класса может быть вызван (см. выше), чтобы получить экземпляр класса (см. ниже).

Специальные атрибуты:

__name__

Имя класса.

__module__

Имя модуля, в котором был определен класс.

__dict__

Словарь, содержащий пространство имен класса.

__bases__

Кортеж, содержащий базовые классы в порядке их появления в списке базовых классов.

__doc__

Строка документации класса, или None, если она не определена.

__annotations__

Словарь, содержащий variable annotations, собранные во время выполнения тела класса. О лучших практиках работы с __annotations__ читайте в разделе Лучшие практики использования аннотаций.

__type_params__

Кортеж, содержащий type parameters из generic class.

__static_attributes__

Кортеж, содержащий имена атрибутов данного класса, доступ к которым осуществляется через self.X из любой функции в его теле.

__firstlineno__

Номер строки первой строки определения класса, включая декораторы.

3.2.11. Экземпляры классов

Экземпляр класса создается путем вызова объекта класса (см. выше). У экземпляра класса есть пространство имен, реализованное в виде словаря, в котором в первую очередь ищутся ссылки на атрибуты. Если атрибут там не найден, а класс экземпляра имеет атрибут с таким именем, поиск продолжается в атрибутах класса. Если найден атрибут класса, являющийся объектом пользовательской функции, он преобразуется в объект метода экземпляра, атрибутом __self__ которого является экземпляр. Объекты статических методов и методов классов также преобразуются; см. выше в разделе «Классы». Еще один способ, с помощью которого атрибуты класса, получаемые через его экземпляры, могут отличаться от объектов, хранящихся в __dict__ класса, см. в разделе Реализация дескрипторов. Если атрибут класса не найден, а у класса объекта есть метод __getattr__(), он вызывается для выполнения поиска.

Присвоение и удаление атрибутов обновляет словарь экземпляра, но не словарь класса. Если у класса есть метод __setattr__() или __delattr__(), он вызывается вместо прямого обновления словаря экземпляра.

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

Специальные атрибуты: __dict__ - словарь атрибутов; __class__ - класс экземпляра.

3.2.12. Объекты ввода/вывода (также известные как файловые объекты)

Символ file object означает открытый файл. Для создания файловых объектов доступны различные ярлыки: встроенная функция open(), а также os.popen(), os.fdopen() и метод makefile() объектов сокетов (и, возможно, другие функции или методы, предоставляемые модулями расширения).

Объекты sys.stdin, sys.stdout и sys.stderr инициализируются файловыми объектами, соответствующими стандартным потокам ввода, вывода и ошибок интерпретатора; все они открыты в текстовом режиме и поэтому следуют интерфейсу, определенному абстрактным классом io.TextIOBase.

3.2.13. Внутренние типы

Несколько типов, используемых интерпретатором внутри, открыты для пользователя. Их определения могут измениться в будущих версиях интерпретатора, но для полноты картины они упомянуты здесь.

3.2.13.1. Кодовые объекты

Объекты кода представляют собой байтно-компилированный исполняемый код Python, или bytecode. Разница между объектом кода и объектом функции заключается в том, что объект функции содержит явную ссылку на глобалы функции (модуль, в котором она была определена), а объект кода не содержит контекста; также значения аргументов по умолчанию хранятся в объекте функции, а не в объекте кода (поскольку они представляют собой значения, вычисляемые во время выполнения). В отличие от объектов функций, объекты кода неизменяемы и не содержат ссылок (прямых или косвенных) на изменяемые объекты.

3.2.13.1.1. Специальные атрибуты, доступные только для чтения
codeobject.co_name

Имя функции

codeobject.co_qualname

Полное имя функции

Added in version 3.11.

codeobject.co_argcount

Общее количество позиционных parameters (включая только позиционные параметры и параметры со значениями по умолчанию), которые имеет функция

codeobject.co_posonlyargcount

Количество только позиционных parameters (включая аргументы со значениями по умолчанию), которые имеет функция

codeobject.co_kwonlyargcount

Количество аргументов parameters (включая аргументы со значениями по умолчанию), которые имеет функция.

codeobject.co_nlocals

Количество local variables, используемых функцией (включая параметры)

codeobject.co_varnames

A tuple, содержащий имена локальных переменных в функции (начиная с имен параметров)

codeobject.co_cellvars

tuple, содержащий имена local variables, на которые ссылаются вложенные функции внутри функции

codeobject.co_freevars

A tuple, содержащий имена свободных переменных в функции

codeobject.co_code

Строка, представляющая последовательность инструкций bytecode в функции

codeobject.co_consts

tuple, содержащий литералы, используемые bytecode в функции

codeobject.co_names

tuple, содержащий имена, используемые bytecode в функции

codeobject.co_filename

Имя файла, из которого был скомпилирован код

codeobject.co_firstlineno

Номер строки первой строки функции

codeobject.co_lnotab

Строка, кодирующая отображение смещений bytecode на номера строк. Подробности см. в исходном коде интерпретатора.

Не рекомендуется, начиная с версии 3.12: Этот атрибут объектов кода устарел и может быть удален в Python 3.14.

codeobject.co_stacksize

Требуемый размер стека объекта кода

codeobject.co_flags

В integer содержится ряд флагов для интерпретатора.

Для co_flags определены следующие биты флагов: бит 0x04 установлен, если функция использует синтаксис *arguments для приема произвольного числа позиционных аргументов; бит 0x08 установлен, если функция использует синтаксис **keywords для приема произвольных аргументов в виде ключевых слов; бит 0x20 установлен, если функция является генератором. Подробнее о семантике каждого из флагов, которые могут присутствовать, см. в разделе Битовые флаги кодовых объектов.

В объявлениях будущих функций (from __future__ import division) также используются биты в co_flags, чтобы указать, был ли объект кода скомпилирован с включенной функцией: бит 0x2000 устанавливается, если функция была скомпилирована с включенным будущим разделением; биты 0x10 и 0x1000 использовались в ранних версиях Python.

Остальные биты в co_flags зарезервированы для внутреннего использования.

Если объект кода представляет собой функцию, то первым элементом в co_consts будет строка документации функции, или None, если функция не определена.

3.2.13.1.2. Методы на объектах кода
codeobject.co_positions()

Возвращает итерабельную таблицу позиций исходного кода каждой инструкции bytecode в объекте кода.

Итератор возвращает tuple, содержащие (start_line, end_line, start_column, end_column). Кортеж i-th соответствует позиции исходного кода, скомпилированного в единицу кода i-th. Информация в столбцах представляет собой 0-индексированные utf-8 смещения байтов в данной строке исходного кода.

Эта позиционная информация может отсутствовать. Неполный список случаев, когда это может произойти:

  • Запуск интерпретатора с -X no_debug_ranges.

  • Загрузка pyc-файла, скомпилированного при использовании -X no_debug_ranges.

  • Кортежи позиций, соответствующие искусственным инструкциям.

  • Номера строк и столбцов, которые не могут быть представлены из-за ограничений конкретной реализации.

Когда это происходит, некоторые или все элементы кортежа могут быть None.

Added in version 3.11.

Примечание

Эта возможность требует хранения позиций столбцов в объектах кода, что может привести к небольшому увеличению использования диска скомпилированных файлов Python или памяти интерпретатора. Чтобы избежать хранения дополнительной информации и/или отключить печать дополнительной информации о возвратах к трассировке, используйте флаг -X no_debug_ranges флаг командной строки или переменная окружения PYTHONNODEBUGRANGES.

codeobject.co_lines()

Возвращает итератор, содержащий информацию о последовательных диапазонах bytecode. Каждый полученный элемент представляет собой (start, end, lineno) tuple:

  • start (символ int) представляет собой смещение (включительно) начала диапазона bytecode.

  • end (символ int) представляет собой смещение (исключительное) конца диапазона bytecode.

  • lineno - это int, представляющий номер строки в диапазоне bytecode, или None, если байткоды в данном диапазоне не имеют номера строки

Полученные предметы будут обладать следующими свойствами:

  • Первый полученный диапазон будет иметь значение start, равное 0.

  • Диапазоны (start, end) будут неубывающими и последовательными. То есть, для любой пары tuple, start второго будет равен end первого.

  • Никакой диапазон не будет обратным: end >= start для всех троек.

  • Последний tuple, полученный в результате, будет иметь end, равный размеру bytecode.

Допускаются диапазоны нулевой ширины, где start == end. Диапазоны нулевой ширины используются для строк, которые присутствуют в исходном коде, но были удалены компилятором bytecode.

Added in version 3.10.

См.также

PEP 626 - Точные номера строк для отладки и других инструментов.

PEP, в котором был введен метод co_lines().

codeobject.replace(**kwargs)

Возвращает копию объекта кода с новыми значениями для указанных полей.

Объекты кода также поддерживаются общей функцией copy.replace().

Added in version 3.8.

3.2.13.2. Каркасные объекты

Объекты Frame представляют кадры выполнения. Они могут встречаться в traceback objects, а также передаются в зарегистрированные функции трассировки.

3.2.13.2.1. Специальные атрибуты, доступные только для чтения
frame.f_back

Указывает на предыдущий кадр стека (в сторону вызывающей стороны), или None, если это нижний кадр стека

frame.f_code

code object, выполняемый в этом кадре. Доступ к этому атрибуту вызывает auditing event object.__getattr__ с аргументами obj и "f_code".

frame.f_locals

Отображение, используемое кадром для поиска local variables. Если кадр ссылается на optimized scope, то может быть возвращен прокси-объект с возможностью записи.

Изменено в версии 3.13: Возвращает прокси для оптимизированных диапазонов.

frame.f_globals

Словарь, используемый фреймом для поиска global variables.

frame.f_builtins

Словарь, используемый фреймом для поиска built-in (intrinsic) names.

frame.f_lasti

«Точная инструкция» объекта кадра (это индекс в строке bytecode строки code object)

3.2.13.2.2. Специальные атрибуты, доступные для записи
frame.f_trace

Если не None, то это функция, вызываемая для различных событий во время выполнения кода (используется отладчиками). Обычно событие вызывается для каждой новой строки исходного кода (см. f_trace_lines).

frame.f_trace_lines

Установите этот атрибут в значение False, чтобы отключить инициирование события трассировки для каждой строки источника.

frame.f_trace_opcodes

Установите этот атрибут в True, чтобы разрешить запрашивать события для каждого опкода. Обратите внимание, что это может привести к неопределенному поведению интерпретатора, если исключения, вызванные функцией трассировки, перейдут в трассируемую функцию.

frame.f_lineno

Номер текущей строки кадра – запись в этот атрибут из функции трассировки переходит на указанную строку (только для самого нижнего кадра). Отладчик может реализовать команду Jump (она же Set Next Statement) путем записи в этот атрибут.

3.2.13.2.3. Методы объекта фрейма

Объекты фрейма поддерживают один метод:

frame.clear()

Этот метод очищает все ссылки на local variables, принадлежащие кадру. Также, если фрейм принадлежал generator, генератор завершается. Это помогает разорвать циклы ссылок с участием объектов фрейма (например, при перехвате exception и сохранении его traceback для последующего использования).

RuntimeError поднимается, если кадр в данный момент выполняется или приостановлен.

Added in version 3.4.

Изменено в версии 3.13: Попытка очистить приостановленный кадр приводит к появлению RuntimeError (как это всегда происходило с выполняющимися кадрами).

3.2.13.3. Объекты отслеживания

Объекты traceback представляют собой трассировку стека exception. Объект traceback неявно создается при возникновении исключения, а также может быть явно создан вызовом types.TracebackType.

Изменено в версии 3.7: Объекты Traceback теперь можно явно инстанцировать из кода Python.

Для неявно созданных трассировок, когда поиск обработчика исключения разворачивает стек выполнения, на каждом разворачиваемом уровне объект трассировки вставляется перед текущей трассировкой. Когда вводится обработчик исключений, трассировка стека становится доступной программе. (См. раздел Заявление try.) Он доступен как третий элемент кортежа, возвращаемого командой sys.exc_info(), и как атрибут __traceback__ пойманного исключения.

Если программа не содержит подходящего обработчика, трассировка стека записывается (в красивом формате) в стандартный поток ошибок; если интерпретатор интерактивен, она также становится доступной пользователю в виде sys.last_traceback.

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

Специальные атрибуты, доступные только для чтения:

traceback.tb_frame

Указывает на выполнение frame текущего уровня.

Доступ к этому атрибуту вызывает сообщение auditing event object.__getattr__ с аргументами obj и "tb_frame".

traceback.tb_lineno

Указывает номер строки, в которой произошло исключение

traceback.tb_lasti

Указывает на «точную инструкцию».

Номер строки и последняя инструкция в обратном отслеживание могут отличаться от номера строки его frame object, если исключение произошло в операторе try без совпадающего предложения except или с предложением finally.

traceback.tb_next

Специальный записываемый атрибут tb_next - это следующий уровень в трассировке стека (по отношению к кадру, в котором произошло исключение), или None, если следующего уровня нет.

Изменено в версии 3.7: Теперь этот атрибут можно записывать

3.2.13.4. Нарезать объекты

Объекты Slice используются для представления срезов для методов __getitem__(). Они также создаются встроенной функцией slice().

Специальные атрибуты, доступные только для чтения: start - нижняя граница; stop - верхняя граница; step - значение шага; каждый - None, если опущен. Эти атрибуты могут иметь любой тип.

Объекты Slice поддерживают один метод:

slice.indices(self, length)

Этот метод принимает единственный целочисленный аргумент length и вычисляет информацию о срезе, который объект slice описывал бы, если бы применялся к последовательности элементов length. Он возвращает кортеж из трех целых чисел; соответственно, это индексы start и stop и длина step или stride среза. Отсутствующие или выходящие за пределы индексы обрабатываются в соответствии с обычными срезами.

3.2.13.5. Объекты статических методов

Статические объекты методов позволяют преодолеть описанное выше преобразование объектов функций в объекты методов. Статический объект метода - это обертка вокруг любого другого объекта, обычно объекта метода, определяемого пользователем. Когда статический объект метода извлекается из класса или экземпляра класса, возвращаемым объектом является обернутый объект, который не подвергается никаким дальнейшим преобразованиям. Статические объекты методов также можно вызывать. Объекты статических методов создаются встроенным конструктором staticmethod().

3.2.13.6. Объекты методов класса

Объект метода класса, как и объект статического метода, представляет собой обертку вокруг другого объекта, которая изменяет способ получения этого объекта из классов и экземпляров классов. Поведение объектов методов классов при таком извлечении описано выше, в разделе «instance methods». Объекты-методы классов создаются с помощью встроенного конструктора classmethod().

3.3. Специальные имена методов

Класс может реализовать определенные операции, которые вызываются специальным синтаксисом (например, арифметические операции или подзапись и нарезка), определив методы со специальными именами. Это подход Python к operator overloading, позволяющий классам определять свое собственное поведение по отношению к операторам языка. Например, если класс определяет метод с именем __getitem__(), а x является экземпляром этого класса, то x[i] примерно эквивалентен type(x).__getitem__(x, i). За исключением упомянутых случаев, попытки выполнить операцию вызывают исключение, если соответствующий метод не определен (обычно AttributeError или TypeError).

Установка специального метода в None означает, что соответствующая операция недоступна. Например, если класс устанавливает __iter__() в None, он не является итерируемым, поэтому вызов iter() на его экземплярах вызовет TypeError (без возврата к __getitem__()). [2]

При реализации класса, эмулирующего какой-либо встроенный тип, важно, чтобы эмуляция была реализована только в той степени, в которой это имеет смысл для моделируемого объекта. Например, некоторые последовательности могут хорошо работать с извлечением отдельных элементов, но извлечение фрагмента может быть бессмысленным. (Одним из примеров является интерфейс NodeList в объектной модели документа W3C).

3.3.1. Базовая настройка

object.__new__(cls[, ...])

Вызывается для создания нового экземпляра класса cls. __new__() - это статический метод (в специальном регистре, поэтому его не нужно объявлять как таковой), который в качестве первого аргумента принимает класс, экземпляр которого был запрошен. Остальные аргументы - это аргументы, передаваемые в выражение конструктора объекта (вызов класса). Возвращаемым значением __new__() должен быть новый экземпляр объекта (обычно экземпляр cls).

Типичные реализации создают новый экземпляр класса, вызывая метод __new__() суперкласса с помощью super().__new__(cls[, ...]) с соответствующими аргументами, а затем модифицируют вновь созданный экземпляр по мере необходимости, прежде чем вернуть его.

Если при конструировании объекта был вызван метод __new__() и он вернул экземпляр cls, то метод __init__() нового экземпляра будет вызван как __init__(self[, ...]), где self - новый экземпляр, а остальные аргументы те же, что были переданы конструктору объекта.

Если __new__() не возвращает экземпляр cls, то метод __init__() нового экземпляра не будет вызван.

__new__() предназначен в основном для того, чтобы позволить подклассам неизменяемых типов (таких как int, str или tuple) настраивать создание экземпляров. Он также часто переопределяется в пользовательских метаклассах для настройки создания классов.

object.__init__(self[, ...])

Вызывается после создания экземпляра (по __new__()), но до его возврата вызывающему. Аргументами являются те, которые передаются в выражение конструктора класса. Если базовый класс имеет метод __init__(), то метод __init__() производного класса, если таковой имеется, должен явно вызывать его, чтобы обеспечить правильную инициализацию части экземпляра базового класса; например: super().__init__([args...]).

Поскольку __new__() и __init__() работают вместе при конструировании объектов (__new__() для создания и __init__() для настройки), __init__() не может возвращать значения, отличные от None; это приведет к возникновению TypeError во время выполнения.

object.__del__(self)

Вызывается, когда экземпляр собирается быть уничтоженным. Его также называют финализатором или (неправильно) деструктором. Если у базового класса есть метод __del__(), то метод __del__() производного класса, если таковой имеется, должен явно вызывать его, чтобы обеспечить правильное удаление части экземпляра базового класса.

Метод __del__() может (хотя и не рекомендуется!) отложить уничтожение экземпляра, создав новую ссылку на него. Это называется воскрешением объекта. Вызывать ли метод __del__() второй раз, когда воскрешенный объект собирается быть уничтоженным, зависит от реализации; текущая реализация CPython вызывает его только один раз.

Не гарантируется, что методы __del__() будут вызваны для объектов, которые все еще существуют после выхода из интерпретатора.

Примечание

del x не вызывает напрямую x.__del__() — первая уменьшает счетчик ссылок для x на единицу, а вторая вызывается только тогда, когда счетчик ссылок x достигает нуля.

Детали реализации CPython: Цикл ссылок может препятствовать тому, чтобы счетчик ссылок объекта обнулился. В этом случае цикл будет позже обнаружен и удален с помощью cyclic garbage collector. Частой причиной циклов ссылок является ситуация, когда исключение было поймано в локальной переменной. Локальные переменные фрейма ссылаются на исключение, которое ссылается на свой собственный traceback, который ссылается на локальные переменные всех фреймов, попавших в traceback.

См.также

Документация для модуля gc.

Предупреждение

Поскольку методы __del__() вызываются в небезопасных условиях, исключения, возникающие во время их выполнения, игнорируются, и вместо них в sys.stderr выводится предупреждение. В частности:

  • __del__() может быть вызван при выполнении произвольного кода, в том числе из любого произвольного потока. Если __del__() нужно взять блокировку или вызвать любой другой блокирующий ресурс, это может привести к тупику, так как ресурс может быть уже занят кодом, прерванным для выполнения __del__().

  • __del__() может быть выполнена во время завершения работы интерпретатора. Как следствие, глобальные переменные, к которым ему нужно получить доступ (в том числе в других модулях), могут быть уже удалены или установлены в значение None. Python гарантирует, что глобальные переменные, имя которых начинается с одного подчеркивания, удаляются из своего модуля до удаления других глобальных переменных; если других ссылок на такие глобальные переменные не существует, это может помочь убедиться, что импортируемые модули все еще доступны на момент вызова метода __del__().

object.__repr__(self)

Вызывается встроенной функцией repr() для вычисления «официального» строкового представления объекта. Если это вообще возможно, оно должно выглядеть как правильное выражение Python, которое можно использовать для воссоздания объекта с тем же значением (при соответствующем окружении). Если это невозможно, то должна быть возвращена строка вида <...some useful description...>. Возвращаемое значение должно быть строковым объектом. Если класс определяет __repr__(), но не __str__(), то __repr__() также используется, когда требуется «неформальное» строковое представление экземпляров этого класса.

Обычно это используется для отладки, поэтому важно, чтобы представление было информационно насыщенным и однозначным.

object.__str__(self)

Вызывается str(object) и встроенными функциями format() и print() для вычисления «неформального» или хорошо печатаемого строкового представления объекта. Возвращаемое значение должно быть объектом string.

Этот метод отличается от object.__repr__() тем, что не ожидается, что __str__() вернет правильное выражение Python: можно использовать более удобное или краткое представление.

Реализация по умолчанию, определяемая встроенным типом object, вызывает object.__repr__().

object.__bytes__(self)

Вызывается bytes для вычисления байт-строкового представления объекта. В результате должен быть возвращен объект bytes.

object.__format__(self, format_spec)

Вызывается встроенной функцией format() и, соответственно, оценкой formatted string literals и методом str.format() для получения «отформатированного» строкового представления объекта. Аргумент format_spec представляет собой строку, содержащую описание желаемых параметров форматирования. Интерпретация аргумента format_spec зависит от типа, реализующего __format__(), однако большинство классов либо делегируют форматирование одному из встроенных типов, либо используют схожий синтаксис опций форматирования.

Описание стандартного синтаксиса форматирования см. в разделе Мини-язык спецификации формата.

Возвращаемое значение должно быть строковым объектом.

Изменено в версии 3.4: Метод __format__ из object сам по себе вызывает ошибку TypeError, если ему передается любая непустая строка.

Изменено в версии 3.7: object.__format__(x, '') теперь эквивалентен str(x), а не format(str(x), '').

object.__lt__(self, other)
object.__le__(self, other)
object.__eq__(self, other)
object.__ne__(self, other)
object.__gt__(self, other)
object.__ge__(self, other)

Это так называемые методы «богатого сравнения». Соответствие между символами операторов и именами методов следующее: 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).

Метод богатого сравнения может возвращать синглтон NotImplemented, если он не реализует операцию для данной пары аргументов. По условию, при успешном сравнении возвращаются значения False и True. Однако эти методы могут возвращать любое значение, поэтому если оператор сравнения используется в булевом контексте (например, в условии оператора if), Python вызовет bool() для значения, чтобы определить, является ли результат истинным или ложным.

По умолчанию object реализует __eq__(), используя is, возвращая NotImplemented в случае ложного сравнения: True if x is y else NotImplemented. Для __ne__() по умолчанию делегируется __eq__() и инвертирует результат, если он не равен NotImplemented. Других подразумеваемых отношений между операторами сравнения или реализациями по умолчанию не существует; например, истинность (x<y or x==y) не подразумевает x<=y. Чтобы автоматически генерировать операции упорядочивания из одной корневой операции, смотрите functools.total_ordering().

См. параграф о __hash__() для некоторых важных замечаний по созданию объектов hashable, которые поддерживают пользовательские операции сравнения и могут использоваться в качестве ключей словаря.

Не существует версий этих методов с подмененными аргументами (используемых в тех случаях, когда левый аргумент не поддерживает операцию, а правый поддерживает); скорее, __lt__() и __gt__() являются отражением друг друга, __le__() и __ge__() - отражением друг друга, а __eq__() и __ne__() - собственным отражением. Если операнды разных типов, и тип правого операнда является прямым или косвенным подклассом типа левого операнда, приоритет имеет отраженный метод правого операнда, в противном случае приоритет имеет метод левого операнда. Виртуальный подкласс не рассматривается.

Если ни один подходящий метод не возвращает значение, отличное от NotImplemented, операторы == и != возвращаются к is и is not соответственно.

object.__hash__(self)

Вызывается встроенной функцией hash() и для операций над членами хешированных коллекций, включая set, frozenset и dict. Метод __hash__() должен возвращать целое число. Единственным обязательным свойством является то, что объекты, которые сравниваются одинаково, имеют одинаковое хэш-значение; рекомендуется смешивать хэш-значения компонентов объекта, которые также играют роль в сравнении объектов, упаковывая их в кортеж и хэшируя кортеж. Пример:

def __hash__(self):
    return hash((self.name, self.nick, self.color))

Примечание

hash() усекает значение, возвращаемое из пользовательского метода __hash__() объекта, до размера Py_ssize_t. Обычно это 8 байт в 64-битных сборках и 4 байта в 32-битных сборках. Если __hash__() объекта должен взаимодействовать со сборками с разным размером бит, обязательно проверьте ширину во всех поддерживаемых сборках. Простой способ сделать это - использовать python -c "import sys; print(sys.hash_info.width)".

Если класс не определяет метод __eq__(), он не должен определять и операцию __hash__(); если он определяет __eq__(), но не __hash__(), его экземпляры нельзя будет использовать в качестве элементов хэшируемых коллекций. Если класс определяет мутабельные объекты и реализует метод __eq__(), он не должен реализовывать __hash__(), поскольку реализация коллекций hashable требует, чтобы хэш-значение ключа было неизменяемым (если хэш-значение объекта изменится, он окажется в неправильном хэш-бакете).

Определяемые пользователем классы по умолчанию имеют методы __eq__() и __hash__(); с ними все объекты сравниваются неравными (кроме самих себя), а x.__hash__() возвращает соответствующее значение, такое, что x == y подразумевает и x is y, и hash(x) == hash(y).

Класс, который переопределяет __eq__() и не определяет __hash__(), будет иметь __hash__(), неявно установленный в None. Если метод __hash__() класса имеет значение None, экземпляры класса будут вызывать соответствующее TypeError при попытке программы получить их хэш-значение, а также будут правильно идентифицированы как нехэшируемые при проверке isinstance(obj, collections.abc.Hashable).

Если класс, переопределяющий __eq__(), должен сохранить реализацию __hash__() из родительского класса, интерпретатору нужно сообщить об этом явно, установив __hash__ = <ParentClass>.__hash__.

Если класс, не переопределяющий __eq__(), хочет отказаться от поддержки хэширования, он должен включить __hash__ = None в определение класса. Класс, определяющий свой собственный __hash__(), который явно поднимает TypeError, будет неверно идентифицирован как хэшируемый вызовом isinstance(obj, collections.abc.Hashable).

Примечание

По умолчанию значения __hash__() объектов str и bytes «солятся» непредсказуемым случайным значением. Хотя они остаются постоянными в рамках отдельного процесса Python, они не предсказуемы между повторными вызовами Python.

Это предназначено для защиты от отказа в обслуживании, вызванного тщательно подобранными входными данными, которые используют наихудшую производительность вставки диктанта, O(n2) сложности. Подробности см. на сайте http://ocert.org/advisories/ocert-2011-003.html.

Изменение хэш-значений влияет на порядок итерации множеств. Python никогда не давал гарантий относительно этого порядка (и он обычно различается в 32-битных и 64-битных сборках).

См. также PYTHONHASHSEED.

Изменено в версии 3.3: Рандомизация хэша включена по умолчанию.

object.__bool__(self)

Вызывается для реализации проверки истинности значения и встроенной операции bool(); должен возвращать False или True. Если этот метод не определен, вызывается __len__(), если он определен, и объект считается истинным, если его результат ненулевой. Если класс не определяет ни __len__(), ни __bool__(), все его экземпляры считаются истинными.

3.3.2. Настройка доступа к атрибутам

Следующие методы могут быть определены для настройки значения доступа к атрибутам (использование, присвоение или удаление x.name) для экземпляров класса.

object.__getattr__(self, name)

Вызывается, когда доступ к атрибуту по умолчанию не дает результата AttributeError (либо __getattribute__() вызывает AttributeError, поскольку name не является атрибутом экземпляра или атрибутом в дереве классов для self; либо __get__() свойства name вызывает AttributeError). Этот метод должен либо возвращать (вычисленное) значение атрибута, либо вызывать исключение AttributeError.

Обратите внимание, что если атрибут найден с помощью обычного механизма, вызов __getattr__() не производится. (Это намеренная асимметрия между __getattr__() и __setattr__().) Это сделано как из соображений эффективности, так и потому, что иначе __getattr__() не имела бы возможности получить доступ к другим атрибутам экземпляра. Обратите внимание, что, по крайней мере, для переменных экземпляра вы можете полностью контролировать ситуацию, не вставляя никаких значений в словарь атрибутов экземпляра (а вместо этого вставляя их в другой объект). О том, как получить полный контроль над доступом к атрибутам, читайте в методе __getattribute__() ниже.

object.__getattribute__(self, name)

Вызывается безусловно для реализации доступа к атрибутам для экземпляров класса. Если класс также определяет __getattr__(), последний метод не будет вызываться, пока __getattribute__() не вызовет его явно или не вызовет исключение AttributeError. Этот метод должен возвращать (вычисленное) значение атрибута или вызывать исключение AttributeError. Чтобы избежать бесконечной рекурсии в этом методе, его реализация должна всегда вызывать одноименный метод базового класса для доступа к любым необходимым атрибутам, например object.__getattribute__(self, name).

Примечание

Этот метод все еще можно обойти при поиске специальных методов в результате неявного вызова через синтаксис языка или built-in functions. См. Поиск специального метода.

Поднимает auditing event object.__getattr__ с аргументами obj, name.

object.__setattr__(self, name, value)

Вызывается при попытке присвоения атрибута. Вызывается вместо обычного механизма (т.е. сохранения значения в словаре экземпляра). name - имя атрибута, value - значение, которое должно быть ему присвоено.

Если __setattr__() хочет присвоить атрибут экземпляра, он должен вызвать метод базового класса с тем же именем, например object.__setattr__(self, name, value).

Поднимает auditing event object.__setattr__ с аргументами obj, name, value.

object.__delattr__(self, name)

Аналогично __setattr__(), но для удаления атрибутов вместо присвоения. Это должно быть реализовано только в том случае, если del obj.name имеет смысл для объекта.

Поднимает auditing event object.__delattr__ с аргументами obj, name.

object.__dir__(self)

Вызывается при вызове dir() на объекте. Должен быть возвращен итерируемый объект. dir() преобразует возвращаемый итерабельный список в список и сортирует его.

3.3.2.1. Настройка доступа к атрибутам модуля

Специальные имена __getattr__ и __dir__ также могут быть использованы для настройки доступа к атрибутам модуля. Функция __getattr__ на уровне модуля должна принимать один аргумент, который является именем атрибута, и возвращать вычисленное значение или вызывать AttributeError. Если атрибут не найден в объекте модуля обычным поиском, то есть object.__getattribute__(), то __getattr__ ищется в модуле __dict__ перед вызовом AttributeError. Если атрибут найден, он вызывается с именем атрибута и возвращается результат.

Функция __dir__ не должна принимать никаких аргументов и возвращает итерабельную строку, представляющую имена, доступные в модуле. Если эта функция присутствует, она отменяет стандартный поиск dir() по модулю.

Для более тонкой настройки поведения модуля (установка атрибутов, свойств и т. д.) можно установить атрибут __class__ объекта модуля на подкласс types.ModuleType. Например:

import sys
from types import ModuleType

class VerboseModule(ModuleType):
    def __repr__(self):
        return f'Verbose {self.__name__}'

    def __setattr__(self, attr, value):
        print(f'Setting {attr}...')
        super().__setattr__(attr, value)

sys.modules[__name__].__class__ = VerboseModule

Примечание

Определение модуля __getattr__ и установка модуля __class__ влияют только на поиск с использованием синтаксиса доступа к атрибутам - прямое обращение к глобалам модуля (как с помощью кода внутри модуля, так и через ссылку на словарь глобалов модуля) не затрагивается.

Изменено в версии 3.5: Атрибут модуля __class__ теперь доступен для записи.

Added in version 3.7: Атрибуты модулей __getattr__ и __dir__.

См.также

PEP 562 - Модуль __getattr__ и __dir__

Описывает функции __getattr__ и __dir__ на модулях.

3.3.2.2. Реализация дескрипторов

Следующие методы применяются только тогда, когда экземпляр класса, содержащего метод (так называемый класс дескриптор), появляется в классе владельца (дескриптор должен находиться либо в словаре классов владельца, либо в словаре классов одного из его родителей). В приведенных ниже примерах под «атрибутом» подразумевается атрибут, имя которого является ключом свойства в классе-владельце __dict__.

object.__get__(self, instance, owner=None)

Вызывается для получения атрибута класса-владельца (доступ к атрибуту класса) или экземпляра этого класса (доступ к атрибуту экземпляра). Необязательный аргумент owner - это класс-владелец, а instance - это экземпляр, через который был получен доступ к атрибуту, или None, если доступ к атрибуту осуществляется через owner.

Этот метод должен возвращать вычисленное значение атрибута или вызывать исключение AttributeError.

PEP 252 указывает, что __get__() можно вызывать с одним или двумя аргументами. Встроенные дескрипторы Python поддерживают эту спецификацию; однако, вероятно, некоторые сторонние инструменты имеют дескрипторы, требующие оба аргумента. Собственная реализация __getattribute__() в Python всегда передает оба аргумента, независимо от того, требуются они или нет.

object.__set__(self, instance, value)

Вызывается для установки атрибута экземпляра instance класса-владельца в новое значение, value.

Обратите внимание, что добавление __set__() или __delete__() изменяет тип дескриптора на «дескриптор данных». Более подробную информацию см. в разделе Вызов дескрипторов.

object.__delete__(self, instance)

Вызывается для удаления атрибута у экземпляра экземпляра класса-владельца.

У экземпляров дескрипторов также может присутствовать атрибут __objclass__:

object.__objclass__

Атрибут __objclass__ интерпретируется модулем inspect как указание класса, в котором был определен данный объект (его установка может помочь в изучении динамических атрибутов класса во время выполнения). Для вызываемых объектов он может указывать, что в качестве первого позиционного аргумента ожидается или требуется экземпляр данного типа (или подкласса) (например, CPython устанавливает этот атрибут для несвязанных методов, реализованных на C).

3.3.2.3. Вызов дескрипторов

В общем случае дескриптор - это атрибут объекта с «поведением привязки», доступ к атрибуту которого переопределен методами протокола дескрипторов: __get__(), __set__() и __delete__(). Если любой из этих методов определен для объекта, говорят, что он является дескриптором.

Поведение по умолчанию при доступе к атрибутам - это получение, установка или удаление атрибута из словаря объекта. Например, у a.x есть цепочка поиска, начинающаяся с a.__dict__['x'], затем type(a).__dict__['x'] и далее через базовые классы type(a), не считая метаклассов.

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

Отправной точкой для вызова дескриптора является привязка, a.x. То, как будут собраны аргументы, зависит от a:

Прямой вызов

Самый простой и наименее распространенный вызов - это когда пользовательский код напрямую вызывает метод дескриптора: x.__get__(a).

Привязка экземпляра

При привязке к экземпляру объекта a.x преобразуется в вызов: type(a).__dict__['x'].__get__(a, type(a)).

Привязка к классу

При привязке к классу A.x преобразуется в вызов: A.__dict__['x'].__get__(None, A).

Суперпереплет

Точечный поиск, например super(A, a).x, ищет a.__class__.__mro__ для базового класса B, следующего за A, а затем возвращает B.__dict__['x'].__get__(a, A). Если это не дескриптор, то x возвращается без изменений.

Для привязок экземпляров приоритет вызова дескриптора зависит от того, какие методы дескриптора определены. Дескриптор может определять любую комбинацию __get__(), __set__() и __delete__(). Если он не определяет __get__(), то обращение к атрибуту вернет сам объект дескриптора, если только в словаре экземпляров объекта нет соответствующего значения. Если дескриптор определяет __set__() и/или __delete__(), он является дескриптором данных; если он не определяет ни одного из них, он является дескриптором без данных. Обычно дескрипторы данных определяют и __get__(), и __set__(), в то время как дескрипторы, не относящиеся к данным, имеют только метод __get__(). Дескрипторы данных с определенными __get__() и __set__() (и/или __delete__()) всегда переопределяют переопределение в словаре экземпляров. В отличие от этого, дескрипторы, не относящиеся к данным, могут быть переопределены экземплярами.

Методы Python (включая методы, украшенные символами @staticmethod и @classmethod) реализованы как дескрипторы, не содержащие данных. Соответственно, экземпляры могут переопределять и переопределять методы. Это позволяет отдельным экземплярам получать поведение, отличающееся от поведения других экземпляров того же класса.

Функция property() реализована как дескриптор данных. Соответственно, экземпляры не могут переопределять поведение свойства.

3.3.2.4. __слоты__

__slots__ позволяют нам явно объявлять члены данных (например, свойства) и запрещают создание __dict__ и __weakref__ (если они не объявлены явно в __slots__ или не доступны в родителе).

Экономия места по сравнению с использованием __dict__ может быть значительной. Скорость поиска атрибутов также может быть значительно увеличена.

object.__slots__

Этой переменной класса можно присвоить строку, итерируемую переменную или последовательность строк с именами переменных, используемых экземплярами. __slots__ резервирует место для объявленных переменных и предотвращает автоматическое создание __dict__ и __weakref__ для каждого экземпляра.

Указания по использованию __slots__:

  • При наследовании от класса без __slots__ атрибуты __dict__ и __weakref__ экземпляров всегда будут доступны.

  • Без переменной __dict__ экземпляры не могут быть назначены новым переменным, не перечисленным в определении __slots__. Попытки присвоить имя переменной, не указанной в списке, приводят к появлению AttributeError. Если требуется динамическое присвоение новых переменных, то добавьте '__dict__' к последовательности строк в объявлении __slots__.

  • Без переменной __weakref__ для каждого экземпляра классы, определяющие __slots__, не поддерживают weak references для своих экземпляров. Если поддержка слабых ссылок необходима, то добавьте '__weakref__' к последовательности строк в объявлении __slots__.

  • __slots__ реализуются на уровне класса путем создания descriptors для каждого имени переменной. В результате атрибуты класса не могут быть использованы для установки значений по умолчанию для переменных экземпляра, определенных __slots__; в противном случае атрибут класса перезапишет назначение дескриптора.

  • Действие объявления __slots__ не ограничивается классом, в котором оно определено. Объявленные в родительском классе __slots__ доступны в дочерних классах. Однако дочерние подклассы получат __dict__ и __weakref__, если они также не определят __slots__ (которые должны содержать только имена любых дополнительных слотов).

  • Если класс определяет слот, также определенный в базовом классе, переменная экземпляра, определенная слотом базового класса, становится недоступной (за исключением получения ее дескриптора непосредственно из базового класса). Это делает смысл программы неопределенным. В будущем может быть добавлена проверка для предотвращения этого.

  • TypeError будет поднят, если для класса, производного от "variable-length" built-in type, такого как int, bytes и tuple, определены непустые __slots__.

  • Любая нестрока iterable может быть назначена на __slots__.

  • Если для назначения __слотов__ используется dictionary, то в качестве имен слотов будут использоваться ключи словаря. Значения словаря можно использовать для создания документальных строк для каждого атрибута, которые будут распознаваться inspect.getdoc() и отображаться в выводе help().

  • Назначение __class__ работает только в том случае, если оба класса имеют одинаковые __slots__.

  • Можно использовать Multiple inheritance с несколькими слотовыми родительскими классами, но только один родитель может иметь атрибуты, созданные слотами (остальные базы должны иметь пустые макеты слотов) - нарушения вызывают TypeError.

  • Если для __slots__ используется iterator, то для каждого из значений итератора будет создан descriptor. Однако атрибут __slots__ будет пустым итератором.

3.3.3. Настройка создания классов

Когда класс наследует от другого класса, __init_subclass__() вызывается на родительском классе. Таким образом, можно писать классы, которые изменяют поведение подклассов. Это тесно связано с декораторами классов, но если декораторы классов влияют только на конкретный класс, к которому они применяются, то __init_subclass__ применяется только к будущим подклассам класса, определяющего метод.

classmethod object.__init_subclass__(cls)

Этот метод вызывается всякий раз, когда содержащий класс становится подклассом. В этом случае cls является новым подклассом. Если этот метод определен как обычный метод экземпляра, он неявно преобразуется в метод класса.

Аргументы ключевых слов, передаваемые новому классу, передаются в __init_subclass__ родительского класса. Для совместимости с другими классами, использующими __init_subclass__, следует убрать нужные аргументы ключевых слов, а остальные передать базовому классу, как в:

class Philosopher:
    def __init_subclass__(cls, /, default_name, **kwargs):
        super().__init_subclass__(**kwargs)
        cls.default_name = default_name

class AustralianPhilosopher(Philosopher, default_name="Bruce"):
    pass

Реализация по умолчанию object.__init_subclass__ ничего не делает, но вызывает ошибку, если ее вызывают с какими-либо аргументами.

Примечание

Подсказка метакласса metaclass потребляется остальными механизмами типов и никогда не передается реализациям __init_subclass__. К реальному метаклассу (а не к явному намеку) можно обратиться как к type(cls).

Added in version 3.6.

Когда класс создан, type.__new__() сканирует переменные класса и выполняет обратные вызовы к ним с помощью хука __set_name__().

object.__set_name__(self, owner, name)

Автоматически вызывается при создании класса-владельца owner. Объект был назначен name в этом классе:

class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')

Если переменная класса назначена после создания класса, то __set_name__() не будет вызвана автоматически. При необходимости __set_name__() можно вызвать напрямую:

class A:
   pass

c = C()
A.x = c                  # The hook is not called
c.__set_name__(A, 'x')   # Manually invoke the hook

Более подробную информацию см. в разделе Создание объекта класса.

Added in version 3.6.

3.3.3.1. Метаклассы

По умолчанию классы создаются с помощью type(). Тело класса выполняется в новом пространстве имен, а имя класса локально привязывается к результату type(name, bases, namespace).

Процесс создания класса можно настроить, передав аргумент ключевого слова metaclass в строке определения класса или унаследовав от существующего класса, содержащего такой аргумент. В следующем примере оба MyClass и MySubclass являются экземплярами Meta:

class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass

Любые другие аргументы ключевого слова, указанные в определении класса, передаются во все операции с метаклассом, описанные ниже.

Когда выполняется определение класса, происходят следующие действия:

  • Записи по ТОиР разрешены;

  • определяется соответствующий метакласс;

  • подготовлено пространство имен класса;

  • выполняется тело класса;

  • создается объект класса.

3.3.3.2. Урегулирование записей по ТОиР

object.__mro_entries__(self, bases)

Если база, встречающаяся в определении класса, не является экземпляром type, то на базе ищется метод __mro_entries__(). Если метод __mro_entries__() найден, то база заменяется результатом вызова __mro_entries__() при создании класса. Метод вызывается с исходным кортежем баз, переданным в параметре bases, и должен вернуть кортеж классов, которые будут использоваться вместо базы. Возвращаемый кортеж может быть пустым: в этом случае исходная база игнорируется.

См.также

types.resolve_bases()

Динамически разрешайте базы, которые не являются экземплярами type.

types.get_original_bases()

Получение «исходных баз» класса до модификации __mro_entries__().

PEP 560

Поддержка модуля типизации и общих типов.

3.3.3.3. Определение подходящего метакласса

Подходящий метакласс для определения класса определяется следующим образом:

  • если не указаны базы и явный метакласс, то используется type();

  • Если задан явный метакласс и он не является экземпляром type(), то он используется непосредственно в качестве метакласса;

  • Если в качестве явного метакласса указан экземпляр type() или определены базы, то используется наиболее производный метакласс.

Наиболее производный метакласс выбирается из явно указанного метакласса (если таковой имеется) и метаклассов (т.е. type(cls)) всех указанных базовых классов. Наиболее производным метаклассом является тот, который является подтипом всех этих метаклассов-кандидатов. Если ни один из метаклассов-кандидатов не удовлетворяет этому критерию, то определение класса завершится неудачей с результатом TypeError.

3.3.3.4. Подготовка пространства имен класса

После определения подходящего метакласса подготавливается пространство имен класса. Если у метакласса есть атрибут __prepare__, он вызывается как namespace = metaclass.__prepare__(name, bases, **kwds) (при этом дополнительные аргументы-ключи, если таковые имеются, берутся из определения класса). Метод __prepare__ должен быть реализован как classmethod. Пространство имен, возвращаемое __prepare__, передается в __new__, но при создании конечного объекта класса это пространство имен копируется в новый dict.

Если у метакласса нет атрибута __prepare__, то пространство имен класса инициализируется как пустое упорядоченное отображение.

См.также

PEP 3115 - Метаклассы в Python 3000

Введено крючок пространства имен __prepare__.

3.3.3.5. Выполнение тела класса

Тело класса выполняется (приблизительно) как exec(body, globals(), namespace). Ключевое отличие от обычного вызова exec() заключается в том, что лексический охват позволяет телу класса (включая любые методы) ссылаться на имена из текущего и внешнего охватов, когда определение класса находится внутри функции.

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

3.3.3.6. Создание объекта класса

После того как пространство имен класса было заполнено путем выполнения тела класса, объект класса создается вызовом metaclass(name, bases, namespace, **kwds) (дополнительные ключевые слова, передаваемые здесь, аналогичны тем, что передаются в __prepare__).

Именно на этот объект класса будет ссылаться нулевой аргумент super(). __class__ - это неявная ссылка на закрытие, создаваемая компилятором, если какие-либо методы в теле класса ссылаются на __class__ или super. Это позволяет форме super() с нулевым аргументом правильно идентифицировать определяемый класс на основе лексического анализа, в то время как класс или экземпляр, который был использован для текущего вызова, идентифицируется на основе первого аргумента, переданного методу.

Детали реализации CPython: В CPython 3.6 и более поздних версиях ячейка __class__ передается в метакласс как запись __classcell__ в пространстве имен класса. Если она присутствует, ее необходимо распространить до вызова type.__new__, чтобы класс был инициализирован правильно. Если этого не сделать, то в Python 3.8 это приведет к ошибке RuntimeError.

При использовании метакласса по умолчанию type или любого метакласса, который в конечном итоге вызывает type.__new__, после создания объекта класса выполняются следующие дополнительные действия по настройке:

  1. Метод type.__new__ собирает все атрибуты в пространстве имен класса, которые определяют метод __set_name__();

  2. Эти методы __set_name__ вызываются с указанием определяемого класса и назначенного имени конкретного атрибута;

  3. Хук __init_subclass__() вызывается на непосредственном родителе нового класса в порядке разрешения его методов.

После создания объекта класса он передается декораторам класса, включенным в определение класса (если таковые имеются), и полученный объект привязывается в локальном пространстве имен к определенному классу.

Когда новый класс создается с помощью type.__new__, объект, указанный в качестве параметра пространства имен, копируется в новое упорядоченное отображение, а исходный объект отбрасывается. Новая копия оборачивается в прокси, доступный только для чтения, который становится атрибутом __dict__ объекта класса.

См.также

PEP 3135 - Новый супер

Описывает неявную ссылку на закрытие __class__.

3.3.3.7. Использование метаклассов

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

3.3.4. Настройка проверок экземпляров и подклассов

Следующие методы используются для переопределения поведения по умолчанию встроенных функций isinstance() и issubclass().

В частности, метакласс abc.ABCMeta реализует эти методы, чтобы позволить добавлять абстрактные базовые классы (ABC) в качестве «виртуальных базовых классов» к любому классу или типу (включая встроенные типы), в том числе к другим ABC.

class.__instancecheck__(self, instance)

Возвращает true, если instance следует считать (прямым или косвенным) экземпляром class. Если определено, вызывается для реализации isinstance(instance, class).

class.__subclasscheck__(self, subclass)

Возвращает true, если subclass следует считать (прямым или косвенным) подклассом class. Если определено, вызывается для реализации issubclass(subclass, class).

Обратите внимание, что эти методы ищутся в типе (метаклассе) класса. Они не могут быть определены как методы класса в самом классе. Это соответствует поиску специальных методов, которые вызываются у экземпляров, только в этом случае экземпляр сам является классом.

См.также

PEP 3119 - Представляем абстрактные базовые классы

Включает спецификацию для настройки поведения isinstance() и issubclass() через __instancecheck__() и __subclasscheck__(), с мотивацией этой функциональности в контексте добавления в язык абстрактных базовых классов (см. модуль abc).

3.3.5. Эмуляция общих типов

При использовании type annotations часто полезно параметризировать generic type, используя нотацию квадратных скобок Python. Например, аннотация list[int] может использоваться для обозначения list, в котором все элементы имеют тип int.

См.также

PEP 484 - Тип Подсказки

Знакомство с основой Python для аннотаций типов

Generic Alias Types

Документация для объектов, представляющих параметризованные общие классы

Дженерики, user-defined generics и typing.Generic.

Документация о том, как реализовать общие классы, которые могут быть параметризованы во время выполнения и поняты статическими средствами проверки типов.

Класс, как правило, может быть параметризован только в том случае, если он определяет специальный метод класса __class_getitem__().

classmethod object.__class_getitem__(cls, key)

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

Когда __class_getitem__() определен на классе, он автоматически является методом класса. Поэтому нет необходимости украшать его @classmethod, когда он определен.

3.3.5.1. Назначение __class_getitem__.

Цель __class_getitem__() - позволить параметризацию во время выполнения стандартных библиотек общих классов, чтобы легче было применять type hints к этим классам.

Чтобы реализовать собственные общие классы, которые могут быть параметризованы во время выполнения и поняты статическими средствами проверки типов, пользователи должны либо наследоваться от стандартного библиотечного класса, который уже реализует __class_getitem__(), либо наследоваться от typing.Generic, который имеет свою собственную реализацию __class_getitem__().

Пользовательские реализации __class_getitem__() для классов, определенных вне стандартной библиотеки, могут быть не поняты сторонними программами проверки типов, такими как mypy. Использование __class_getitem__() в любом классе для целей, отличных от подсказки типа, не рекомендуется.

3.3.5.2. __class_getitem__ против __getitem__

Обычно subscription объекта, заключенного в квадратные скобки, вызывает метод экземпляра __getitem__(), определенный для класса объекта. Однако если подписываемый объект сам является классом, вместо него может быть вызван метод класса __class_getitem__(). Метод __class_getitem__() должен возвращать объект GenericAlias, если он правильно определен.

Представляя expression obj[x], интерпретатор Python принимает решение о том, следует ли вызывать __getitem__() или __class_getitem__(), примерно следующим образом:

from inspect import isclass

def subscribe(obj, x):
    """Return the result of the expression 'obj[x]'"""

    class_of_obj = type(obj)

    # If the class of obj defines __getitem__,
    # call class_of_obj.__getitem__(obj, x)
    if hasattr(class_of_obj, '__getitem__'):
        return class_of_obj.__getitem__(obj, x)

    # Else, if obj is a class and defines __class_getitem__,
    # call obj.__class_getitem__(x)
    elif isclass(obj) and hasattr(obj, '__class_getitem__'):
        return obj.__class_getitem__(x)

    # Else, raise an exception
    else:
        raise TypeError(
            f"'{class_of_obj.__name__}' object is not subscriptable"
        )

В Python все классы сами являются экземплярами других классов. Класс класса известен как metaclass этого класса, а большинство классов имеют класс type в качестве своего метакласса. type не определяет __getitem__(), а значит, такие выражения, как list[int], dict[str, float] и tuple[str, bytes], приводят к вызову __class_getitem__():

>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> type(dict) == type(list) == type(tuple) == type(str) == type(bytes)
True
>>> # "list[int]" calls "list.__class_getitem__(int)"
>>> list[int]
list[int]
>>> # list.__class_getitem__ returns a GenericAlias object:
>>> type(list[int])
<class 'types.GenericAlias'>

Однако если класс имеет пользовательский метакласс, определяющий __getitem__(), подписка на него может привести к другому поведению. Пример этого можно найти в модуле enum:

>>> from enum import Enum
>>> class Menu(Enum):
...     """A breakfast menu"""
...     SPAM = 'spam'
...     BACON = 'bacon'
...
>>> # Enum classes have a custom metaclass:
>>> type(Menu)
<class 'enum.EnumMeta'>
>>> # EnumMeta defines __getitem__,
>>> # so __class_getitem__ is not called,
>>> # and the result is not a GenericAlias object:
>>> Menu['SPAM']
<Menu.SPAM: 'spam'>
>>> type(Menu['SPAM'])
<enum 'Menu'>

См.также

PEP 560 - Ядро Поддержка типизации модульных и общих типов

Представляем __class_getitem__() и рассказываем, в каких случаях subscription приводит к вызову __class_getitem__() вместо __getitem__().

3.3.6. Эмуляция вызываемых объектов

object.__call__(self[, args...])

Вызывается, когда экземпляр «вызывается» как функция; если этот метод определен, то x(arg1, arg2, ...) примерно равняется type(x).__call__(x, arg1, ...).

3.3.7. Эмуляция типов контейнеров

Следующие методы могут быть определены для реализации объектов-контейнеров. Обычно контейнеры представляют собой sequences (например, lists или tuples) или mappings (например, dictionaries), но могут представлять и другие контейнеры. Первый набор методов используется либо для эмуляции последовательности, либо для эмуляции отображения; разница в том, что для последовательности допустимыми ключами должны быть целые числа k, для которых 0 <= k < N, где N - длина последовательности, или объекты slice, которые определяют диапазон элементов. Также рекомендуется, чтобы отображения предоставляли методы keys(), values(), items(), get(), clear(), setdefault(), pop(), popitem(), copy() и update(), которые ведут себя аналогично методам для стандартных dictionary объектов Python. Модуль collections.abc предоставляет MutableMapping abstract base class, чтобы помочь создать эти методы из базового набора __getitem__(), __setitem__(), __delitem__() и keys(). Мутабельные последовательности должны предоставлять методы append(), count(), index(), extend(), insert(), pop(), remove(), reverse() и sort(), подобно объектам list стандарта Python. Наконец, типы последовательностей должны реализовывать сложение (то есть конкатенацию) и умножение (то есть повторение), определяя методы __add__(), __radd__(), __iadd__(), __mul__(), __rmul__() и __imul__(), описанные ниже; они не должны определять другие числовые операторы. Рекомендуется, чтобы и отображения, и последовательности реализовывали метод __contains__() для эффективного использования оператора in; для отображений in должен искать ключи отображения, а для последовательностей - значения. Кроме того, рекомендуется, чтобы и отображения, и последовательности

object.__len__(self)

Вызывается для реализации встроенной функции len(). Должна возвращать длину объекта, целое число >=. 0. Кроме того, объект, у которого не определен метод __bool__() и чей метод __len__() возвращает ноль, считается ложным в булевом контексте.

Детали реализации CPython: В CPython длина должна быть не более sys.maxsize. Если длина больше sys.maxsize, некоторые функции (например, len()) могут вызвать OverflowError. Чтобы не вызывать OverflowError при проверке истинности значения, объект должен определить метод __bool__().

object.__length_hint__(self)

Вызывается для реализации operator.length_hint(). Должен возвращать предполагаемую длину объекта (которая может быть больше или меньше фактической). Длина должна быть целым числом >= 0. Возвращаемое значение также может быть NotImplemented, что рассматривается так же, как если бы метод __length_hint__ вообще не существовал. Этот метод является исключительно оптимизацией и никогда не требуется для корректности.

Added in version 3.4.

Примечание

Нарезка выполняется исключительно с помощью следующих трех методов. Вызов типа

a[1:2] = b

переводится как

a[slice(1, 2, None)] = b

и так далее. Отсутствующие элементы среза всегда заполняются символом None.

object.__getitem__(self, key)

Вызывается для реализации оценки типа self[key]. Для типов sequence принимаемые ключи должны быть целыми числами. Опционально они могут поддерживать и объекты slice. Поддержка отрицательных индексов также необязательна. Если key имеет неподходящий тип, может быть выдано сообщение TypeError; если key является значением, выходящим за пределы набора индексов для последовательности (после любой специальной интерпретации отрицательных значений), должно быть выдано сообщение IndexError. Для типов mapping, если key отсутствует (нет в контейнере), должно быть вызвано сообщение KeyError.

Примечание

Циклы for ожидают, что для недопустимых индексов будет вызван сигнал IndexError, чтобы правильно определить конец последовательности.

Примечание

Если subscripting является классом, вместо __getitem__() может быть вызван специальный метод класса __class_getitem__(). Более подробную информацию см. в разделе __class_getitem__ против __getitem__.

object.__setitem__(self, key, value)

Вызывается для реализации присвоения self[key]. То же замечание, что и для __getitem__(). Это должно быть реализовано только для отображений, если объекты поддерживают изменение значений ключей, или если можно добавлять новые ключи, или для последовательностей, если можно заменять элементы. Для неправильных значений ключей должны возникать те же исключения, что и для метода __getitem__().

object.__delitem__(self, key)

Вызывается для реализации удаления self[key]. То же замечание, что и для __getitem__(). Это должно быть реализовано только для отображений, если объекты поддерживают удаление ключей, или для последовательностей, если элементы могут быть удалены из последовательности. Для неправильных значений ключей должны возникать те же исключения, что и для метода __getitem__().

object.__missing__(self, key)

Вызывается dict.__getitem__() для реализации self[key] для подклассов dict, когда ключ не находится в словаре.

object.__iter__(self)

Этот метод вызывается, когда для контейнера требуется iterator. Этот метод должен возвращать новый объект-итератор, который может перебирать все объекты в контейнере. Для отображений он должен перебирать ключи контейнера.

object.__reversed__(self)

Вызывается (если присутствует) встроенным reversed() для реализации обратной итерации. Он должен возвращать новый объект-итератор, который перебирает все объекты в контейнере в обратном порядке.

Если метод __reversed__() не предоставлен, встроенный reversed() вернется к использованию протокола последовательности (__len__() и __getitem__()). Объекты, поддерживающие протокол последовательности, должны предоставлять __reversed__() только в том случае, если они могут обеспечить реализацию, более эффективную, чем та, что предоставляется reversed().

Операторы проверки принадлежности (in и not in) обычно реализуются как итерация через контейнер. Однако объекты-контейнеры могут предоставить следующий специальный метод с более эффективной реализацией, который также не требует, чтобы объект был итерируемым.

object.__contains__(self, item)

Вызывается для реализации операторов проверки принадлежности. Должен возвращать true, если item находится в self, false в противном случае. Для объектов отображения должны учитываться ключи отображения, а не значения или пары ключ-элемент.

Для объектов, которые не определяют __contains__(), тест членства сначала пробует итерацию через __iter__(), затем старый протокол итерации последовательности через __getitem__(), см. this section in the language reference.

3.3.8. Эмуляция числовых типов

Для эмуляции числовых объектов могут быть определены следующие методы. Методы, соответствующие операциям, которые не поддерживаются конкретным видом реализуемого числа (например, побитовые операции для неинтегральных чисел), следует оставить неопределенными.

object.__add__(self, other)
object.__sub__(self, other)
object.__mul__(self, other)
object.__matmul__(self, other)
object.__truediv__(self, other)
object.__floordiv__(self, other)
object.__mod__(self, other)
object.__divmod__(self, other)
object.__pow__(self, other[, modulo])
object.__lshift__(self, other)
object.__rshift__(self, other)
object.__and__(self, other)
object.__xor__(self, other)
object.__or__(self, other)

Эти методы вызываются для реализации операций двоичной арифметики (+, -, *, @, /, //, %, divmod(), pow(), **, <<, >>, &, ^, |). Например, для оценки выражения x + y, где x - экземпляр класса, имеющего метод __add__(), вызывается метод type(x).__add__(x, y). Метод __divmod__() должен быть эквивалентен использованию __floordiv__() и __mod__(); он не должен быть связан с __truediv__(). Обратите внимание, что для поддержки троичной версии встроенной функции pow() следует определить __pow__(), чтобы она принимала необязательный третий аргумент.

Если один из этих методов не поддерживает операцию с указанными аргументами, он должен вернуть NotImplemented.

object.__radd__(self, other)
object.__rsub__(self, other)
object.__rmul__(self, other)
object.__rmatmul__(self, other)
object.__rtruediv__(self, other)
object.__rfloordiv__(self, other)
object.__rmod__(self, other)
object.__rdivmod__(self, other)
object.__rpow__(self, other[, modulo])
object.__rlshift__(self, other)
object.__rrshift__(self, other)
object.__rand__(self, other)
object.__rxor__(self, other)
object.__ror__(self, other)

Эти методы вызываются для реализации двоичных арифметических операций (+, -, *, @, /, //, %, divmod(), pow(), **, <<, >>, &, ^, |) с отраженными (поменяными местами) операндами. Эти функции вызываются только в том случае, если левый операнд не поддерживает соответствующую операцию [3] и операнды имеют разные типы. [4] Например, для оценки выражения x - y, где y - экземпляр класса, имеющего метод __rsub__(), вызывается type(y).__rsub__(y, x), если type(x).__sub__(x, y) возвращает NotImplemented.

Обратите внимание, что троичный pow() не будет пытаться вызвать __rpow__() (правила принуждения стали бы слишком сложными).

Примечание

Если тип правого операнда является подклассом типа левого операнда и этот подкласс предоставляет другую реализацию отраженного метода для операции, этот метод будет вызван перед неотраженным методом левого операнда. Такое поведение позволяет подклассам переопределять операции своих предков.

object.__iadd__(self, other)
object.__isub__(self, other)
object.__imul__(self, other)
object.__imatmul__(self, other)
object.__itruediv__(self, other)
object.__ifloordiv__(self, other)
object.__imod__(self, other)
object.__ipow__(self, other[, modulo])
object.__ilshift__(self, other)
object.__irshift__(self, other)
object.__iand__(self, other)
object.__ixor__(self, other)
object.__ior__(self, other)

Эти методы вызываются для реализации дополненных арифметических присваиваний (+=, -=, *=, @=, /=, //=, %=, **=, <<=, >>=, &=, ^=, |=). Эти методы должны пытаться выполнить операцию на месте (изменяя self) и вернуть результат (который может быть, но не обязательно должен быть self). Если конкретный метод не определен или если он возвращает NotImplemented, дополненное присваивание возвращается к обычным методам. Например, если x - это экземпляр класса с методом __iadd__(), то x += y эквивалентен x = x.__iadd__(y). Если __iadd__() не существует или если x.__iadd__(y) возвращает NotImplemented, то рассматриваются x.__add__(y) и y.__radd__(x), как и при оценке x + y. В некоторых ситуациях дополненное присваивание может приводить к неожиданным ошибкам (см. Почему при сложении a_tuple[i] += [„item“] возникает исключение?), но такое поведение фактически является частью модели данных.

object.__neg__(self)
object.__pos__(self)
object.__abs__(self)
object.__invert__(self)

Вызывается для реализации унарных арифметических операций (-, +, abs() и ~).

object.__complex__(self)
object.__int__(self)
object.__float__(self)

Вызывается для реализации встроенных функций complex(), int() и float(). Должно возвращаться значение соответствующего типа.

object.__index__(self)

Вызывается для реализации operator.index(), а также всякий раз, когда Python нужно без потерь преобразовать числовой объект в целочисленный (например, при нарезке или во встроенных функциях bin(), hex() и oct()). Наличие этого метода указывает на то, что числовой объект является типом integer. Должен возвращать целое число.

Если __int__(), __float__() и __complex__() не определены, то соответствующие встроенные функции int(), float() и complex() возвращаются к __index__().

object.__round__(self[, ndigits])
object.__trunc__(self)
object.__floor__(self)
object.__ceil__(self)

Вызывается для реализации встроенной функции round() и math функций trunc(), floor() и ceil(). Если в __round__() не передано значение ndigits, все эти методы должны возвращать значение объекта, усеченное до Integral (обычно int).

Изменено в версии 3.14: int() больше не делегирует метод __trunc__().

3.3.9. С менеджерами контекста заявлений

context manager - это объект, определяющий контекст времени выполнения, который должен быть установлен при выполнении оператора with. Менеджер контекста обрабатывает вход в контекст времени выполнения и выход из него для выполнения блока кода. Менеджеры контекста обычно вызываются с помощью оператора with (описанного в разделе Заявление with), но также могут быть использованы путем прямого вызова их методов.

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

Дополнительные сведения о менеджерах контекста см. в разделе Типы менеджеров контекста.

object.__enter__(self)

Введите контекст времени выполнения, связанный с этим объектом. Утверждение with свяжет возвращаемое значение этого метода с целью (целями), указанной в пункте as утверждения, если таковые имеются.

object.__exit__(self, exc_type, exc_value, traceback)

Выход из контекста времени выполнения, связанного с этим объектом. Параметры описывают исключение, которое вызвало выход из контекста. Если выход из контекста произошел без исключения, все три аргумента будут равны None.

Если исключение предоставлено, и метод хочет подавить исключение (т.е. предотвратить его распространение), он должен вернуть значение true. В противном случае исключение будет обработано нормально при выходе из этого метода.

Обратите внимание, что методы __exit__() не должны поднимать переданное исключение; за это отвечает вызывающая сторона.

См.также

PEP 343 - Утверждение «с»

Спецификация, история и примеры для оператора Python with.

3.3.10. Настройка позиционных аргументов при сопоставлении шаблонов классов

При использовании имени класса в шаблоне позиционные аргументы в шаблоне по умолчанию не допускаются, т. е. case MyClass(x, y) обычно недействителен без специальной поддержки MyClass. Чтобы иметь возможность использовать такой шаблон, класс должен определить атрибут __match_args__.

object.__match_args__

Этой переменной класса можно присвоить кортеж строк. Когда этот класс используется в шаблоне класса с позиционными аргументами, каждый позиционный аргумент будет преобразован в аргумент ключевого слова, используя соответствующее значение в __match_args__ в качестве ключевого слова. Отсутствие этого атрибута эквивалентно установке значения ().

Например, если MyClass.__match_args__ равно ("left", "center", "right"), это означает, что case MyClass(x, y) эквивалентно case MyClass(left=x, center=y). Обратите внимание, что количество аргументов в шаблоне должно быть меньше или равно количеству элементов в __match_args__; если оно больше, то попытка сопоставления шаблона приведет к ошибке TypeError.

Added in version 3.10.

См.также

PEP 634 - Структурное сопоставление шаблонов

Спецификация для оператора Python match.

3.3.11. Эмуляция типов буферов

Протокол buffer protocol предоставляет объектам Python возможность эффективного доступа к низкоуровневому массиву памяти. Этот протокол реализуется встроенными типами, такими как bytes и memoryview, а сторонние библиотеки могут определять дополнительные типы буферов.

Хотя типы буферов обычно реализуются на языке C, протокол можно реализовать и на Python.

object.__buffer__(self, flags)

Вызывается, когда буфер запрашивается у self (например, конструктором memoryview). Аргумент flags - это целое число, представляющее тип запрашиваемого буфера, влияющее, например, на то, будет ли возвращаемый буфер доступен только для чтения или для записи. inspect.BufferFlags предоставляет удобный способ интерпретации флагов. Метод должен возвращать объект memoryview.

object.__release_buffer__(self, buffer)

Вызывается, когда буфер больше не нужен. Аргумент buffer - это объект memoryview, который ранее был возвращен методом __buffer__(). Метод должен освободить все ресурсы, связанные с буфером. Этот метод должен возвращать None. Объекты буфера, которым не нужно выполнять очистку, не обязаны реализовывать этот метод.

Added in version 3.12.

См.также

PEP 688 - Создание буферного протокола в Python

Представляет методы Python __buffer__ и __release_buffer__.

collections.abc.Buffer

ABC для типов буферов.

3.3.12. Поиск специального метода

Для пользовательских классов неявные вызовы специальных методов гарантированно работают корректно только в том случае, если они определены в типе объекта, а не в словаре экземпляров объекта. Такое поведение является причиной того, что следующий код вызывает исключение:

>>> class C:
...     pass
...
>>> c = C()
>>> c.__len__ = lambda: 5
>>> len(c)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: object of type 'C' has no len()

Причина такого поведения кроется в ряде специальных методов, таких как __hash__() и __repr__(), которые реализуются всеми объектами, включая объекты типа. Если бы для неявного поиска этих методов использовался обычный процесс поиска, то при вызове на самом объекте типа они бы не сработали:

>>> 1 .__hash__() == hash(1)
True
>>> int.__hash__() == hash(int)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: descriptor '__hash__' of 'int' object needs an argument

Неправильная попытка вызвать несвязанный метод класса таким образом иногда называется «путаницей с метаклассом», и ее можно избежать, обходя экземпляр при поиске специальных методов:

>>> type(1).__hash__(1) == hash(1)
True
>>> type(int).__hash__(int) == hash(int)
True

В дополнение к обходу любых атрибутов экземпляра в интересах корректности, неявный поиск специального метода обычно также обходит метод __getattribute__() даже в метаклассе объекта:

>>> class Meta(type):
...     def __getattribute__(*args):
...         print("Metaclass getattribute invoked")
...         return type.__getattribute__(*args)
...
>>> class C(object, metaclass=Meta):
...     def __len__(self):
...         return 10
...     def __getattribute__(*args):
...         print("Class getattribute invoked")
...         return object.__getattribute__(*args)
...
>>> c = C()
>>> c.__len__()                 # Explicit lookup via instance
Class getattribute invoked
10
>>> type(c).__len__(c)          # Explicit lookup via type
Metaclass getattribute invoked
10
>>> len(c)                      # Implicit lookup
10

Такой обход механизма __getattribute__() дает значительные возможности для оптимизации скорости работы интерпретатора за счет некоторой гибкости в работе со специальными методами (специальный метод должен быть установлен на самом объекте класса, чтобы интерпретатор мог его последовательно вызывать).

3.4. Корутины

3.4.1. Ожидаемые объекты

Объект awaitable обычно реализует метод __await__(). Coroutine objects, возвращаемые из async def функций, являются ожидаемыми.

Примечание

Объекты generator iterator, возвращаемые генераторами, украшенными types.coroutine(), также являются ожидаемыми, но они не реализуют __await__().

object.__await__(self)

Должен возвращать значение iterator. Должен использоваться для реализации объектов awaitable. Например, asyncio.Future реализует этот метод, чтобы быть совместимым с выражением await.

Примечание

Язык не накладывает никаких ограничений на тип или значение объектов, выдаваемых итератором, возвращаемым __await__, поскольку это зависит от реализации механизма асинхронного выполнения (например, asyncio), который будет управлять объектом awaitable.

Added in version 3.5.

См.также

PEP 492 для получения дополнительной информации об ожидаемых объектах.

3.4.2. Объекты корутины

Coroutine objects являются объектами awaitable. Выполнение корутины можно контролировать, вызывая __await__() и выполняя итерацию по результату. Когда корутина завершает выполнение и возвращается, итератор поднимает StopIteration, а атрибут value исключения содержит возвращаемое значение. Если короутин вызывает исключение, оно передается итератору. Корутины не должны напрямую вызывать необработанные StopIteration исключения.

Корутины также имеют перечисленные ниже методы, которые аналогичны методам генераторов (см. Методы генератора-итератора). Однако, в отличие от генераторов, корутины не поддерживают итерацию напрямую.

Изменено в версии 3.5.2: Ожидать выполнения coroutine более одного раза - это RuntimeError.

coroutine.send(value)

Запускает или возобновляет выполнение корутины. Если value равно None, это эквивалентно продвижению итератора, возвращенного __await__(). Если значение не равно None, этот метод делегирует метод send() того итератора, который вызвал приостановку работы короутина. Результат (возвращаемое значение, StopIteration или другое исключение) тот же, что и при итерации по возвращаемому значению __await__(), описанной выше.

coroutine.throw(value)
coroutine.throw(type[, value[, traceback]])

Вызывает указанное исключение в корутине. Этот метод делегирует полномочия методу throw() итератора, вызвавшего приостановку коротины, если у него есть такой метод. В противном случае исключение вызывается в точке приостановки. Результат (возвращаемое значение, StopIteration или другое исключение) тот же, что и при итерации по возвращаемому значению __await__(), описанной выше. Если исключение не было поймано в корутине, оно передается обратно вызывающей стороне.

Изменено в версии 3.12: Вторая сигнатура (type[, value[, traceback]]]) устарела и может быть удалена в будущей версии Python.

coroutine.close()

Приводит к очистке и завершению работы корутины. Если выполнение коридора приостановлено, этот метод сначала делегирует метод close() итератора, который вызвал приостановку коридора, если у него есть такой метод. Затем он поднимает GeneratorExit в точке приостановки, заставляя coroutine немедленно очистить себя. И наконец, coroutine помечается как завершившая выполнение, даже если она никогда не была запущена.

Объекты Coroutine автоматически закрываются с помощью описанного выше процесса, когда они собираются быть уничтоженными.

3.4.3. Асинхронные итераторы

Асинхронный итератор* может вызывать асинхронный код в своем методе __anext__.

Асинхронные итераторы можно использовать в операторе async for.

object.__aiter__(self)

Должен возвращать объект асинхронного итератора.

object.__anext__(self)

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

Пример асинхронного итерируемого объекта:

class Reader:
    async def readline(self):
        ...

    def __aiter__(self):
        return self

    async def __anext__(self):
        val = await self.readline()
        if val == b'':
            raise StopAsyncIteration
        return val

Added in version 3.5.

Изменено в версии 3.7: До Python 3.7 __aiter__() мог возвращать ожидаемый, который разрешался в asynchronous iterator.

Начиная с Python 3.7, __aiter__() должен возвращать объект асинхронного итератора. Возврат чего-либо другого приведет к ошибке TypeError.

3.4.4. Асинхронные менеджеры контекста

Асинхронный контекстный менеджер - это контекстный менеджер, который может приостанавливать выполнение в своих методах __aenter__ и __aexit__.

Асинхронные менеджеры контекста можно использовать в операторе async with.

object.__aenter__(self)

Семантически аналогичен __enter__(), с той лишь разницей, что он должен возвращать ожидаемое.

object.__aexit__(self, exc_type, exc_value, traceback)

Семантически аналогичен __exit__(), с той лишь разницей, что он должен возвращать ожидаемое.

Пример класса асинхронного менеджера контекста:

class AsyncContextManager:
    async def __aenter__(self):
        await log('entering context')

    async def __aexit__(self, exc_type, exc, tb):
        await log('exiting context')

Added in version 3.5.

Сноски