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

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

Объекты — это абстракция данных в Python. Все данные в программе Python представлены объектами или отношениями между ними. Даже код представлен объектами.

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

Для CPython, id(x) — это адрес памяти, где хранится x.

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

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

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

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

Заметьте, что использование конкретных средств трассировки или отладки может удерживать объекты живыми, которые в обычных условиях были бы собраны. Также имейте в виду, что перехват исключений в инструкциях try…except может удерживать объекты живыми.

Некоторые объекты содержат ссылки на «внешние» ресурсы, такие как открытые файлы или окна. Разумеется, эти ресурсы освобождаются при удалении объекта сборщиком мусора. Но поскольку сборка мусора не гарантируется, такие объекты также предоставляют явный способ освободить внешний ресурс, обычно через метод close(). Настоятельно рекомендуется явно закрывать такие объекты. Инструкции try…finally и with предоставляют удобные способы сделать это.

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

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

3.2. Иерархия стандартных типов

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

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

3.2.1. None

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

3.2.2. NotImplemented

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

См. Implementing the arithmetic operations для получения подробностей.

Изменено в версии 3.9: Использование NotImplemented в логическом контексте было объявлено устаревшим.

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

3.2.3. Ellipsis

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

3.2.4. numbers.Number

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

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

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

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

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

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

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

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

3.2.4.1. numbers.Integral

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

Примечание

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

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

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

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

Логические значения (bool)

Они представляют логические значения Ложь и Истина. Два объекта, представляющие значения False и True, являются единственными логическими объектами. Логический тип является подтипом целых чисел, и логические значения ведут себя как числа 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.

Полученное значение должно быть неотрицательным целым числом, меньшим количества элементов в последовательности. Если это не так, возбуждается исключение IndexError.

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

Если параметр start отсутствует или равен None, он считается равным нулю. А если не указан или равен None параметр stop, то он считается равным длине последовательности.

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

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

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

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

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

Строки

Строка (str) — это последовательность значений, представляющих символы или, более формально, кодовые точки Юникод. Все кодовые точки в диапазоне от 0 до 0x10FFFF могут быть представлены в строке.

В Python нет отдельного типа символ. Вместо этого каждая кодовая точка в строке представлена объектом строки длиной 1.

Встроенная функция ord() преобразует кодовую точку из строкового представления в целое число из диапазона от 0 до 0x10FFFF; chr() преобразует целое число из диапазона от 0 до 0x10FFFF в соответствующий объект строки длиной 1. Метод str.encode() можно использовать для преобразования str в bytes с использованием указанной кодировки текста, а bytes.decode() позволяет выполнить обратное преобразование.

Кортежи

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

Байты

Объект bytes является неизменяемым массивом. Его элементы — это 8-битные байты, представленные целыми числами из диапазона 0 <= x < 256. Литералы байтов (например, b'abc') и встроенный конструктор bytes() можно использовать для создания объектов 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(). Поскольку такое множество является неизменяемым и хешируемым, его можно использовать как элемент другого множества или как ключ словаря.

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

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

Есть два встроенных типа отображений:

3.2.7.1. Словари

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

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

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

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

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

3.2.7.2. Замороженные словари

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

Добавлено в версии 3.15.

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

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

3.2.8.1. Пользовательские функции

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

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

Атрибут

Значение

function.__builtins__

Ссылка на словарь, содержащий пространство имён встроенных объектов функции.

Добавлено в версии 3.10.

function.__globals__

Ссылка на словарь, содержащий глобальные переменные функции — глобальное пространство имён модуля, в котором функция была определена.

function.__closure__

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

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

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

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

Атрибут

Значение

function.__doc__

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

function.__name__

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

function.__qualname__

Квалифицированное имя функции. См. также: атрибуты __qualname__.

Добавлено в версии 3.3.

function.__module__

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

function.__defaults__

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

function.__code__

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

function.__dict__

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

function.__annotations__

Словарь, содержащий аннотации параметров. Ключами словаря являются имена параметров, а для аннотации возвращаемого значения — 'return', если она задана. См. также: object.__annotations__.

Изменено в версии 3.14: Теперь аннотации вычисляются лениво. См. PEP 649.

function.__annotate__

Функция аннотации для этой функция или None, если у функция нет аннотация. См. object.__annotate__.

Добавлено в версии 3.14.

function.__kwdefaults__

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

function.__type_params__

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

Добавлено в версии 3.12.

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

Текущая реализация CPython поддерживает атрибуты функций только у пользовательских функций. В будущем атрибуты функций могут поддерживаться и у встроенных функций.

Дополнительную информацию об определении функции можно получить из её объекта кода (доступного через атрибут __code__).

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

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

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

method.__self__

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

method.__func__

Ссылается на исходный объект функции.

method.__doc__

Документация метода (то же, что и method.__func__.__doc__). Это строка, если исходная функция имела строку документации, иначе — None.

method.__name__

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

method.__module__

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

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

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

Когда объект метода экземпляра создаётся при получении объекта пользовательской функции из класса через один из его экземпляров, его атрибут __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 — лежащая в основе функция.

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

3.2.8.3. Генераторные функции

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

3.2.8.4. Сопрограммные функции

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

3.2.8.5. Асинхронные генераторные функции

Функция или метод, определённые с помощью async def и содержащие выражение yield, называются асинхронными генераторными функциями. При вызове такая функция возвращает объект асинхронного итератора, который можно использовать в инструкции async for для выполнения тела функции.

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

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

Объект встроенной функции является обёрткой вокруг C-функции. Примерами встроенных функций являются 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 является объектом списка. В этом случае специальный доступный только для чтения атрибут __self__ устанавливается в объект, обозначенный alist. (Атрибут имеет ту же семантику, что и в случае с другими методами экземпляра.)

3.2.8.8. Классы

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

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

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

3.2.9. Модули

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

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

3.2.9.2. Другие доступные для записи атрибуты объектов модулей

Помимо перечисленных выше атрибутов, связанных с импортом, объекты модулей также имеют следующие доступные для записи атрибуты:

module.__doc__

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

module.__annotations__

Словарь, содержащий аннотации переменных, собранные во время выполнения тела модуля. Рекомендации по работе с __annotations__, см. в annotationlib.

Изменено в версии 3.14: Теперь аннотации вычисляются лениво. См. PEP 649.

module.__annotate__

Аннотирующая функция этого модуля или None, если модуль не содержит аннотаций. См. также атрибуты __annotate__.

Добавлено в версии 3.14.

module.__lazy_modules__

Контейнер (объект, реализующий __contains__()) строк с полными квалифицированными именами модулей. Если он определён на уровне модуля, любая обычная инструкция import в этом модуле, целевой модуль которой указан в этом контейнере, рассматривается как ленивый импорт, словно используется ключевое слово lazy. На импорты внутри функций, классов или блоков try/except/finally это не влияет.

Подробности и примеры см. в Совместимость через __lazy_modules__.

Добавлено в версии 3.15.

3.2.9.3. Словари модулей

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

module.__dict__

Пространство имён модуля в виде объекта-словаря. В отличие от всех остальных перечисленных здесь атрибутов, __dict__ нельзя получить как глобальную переменную внутри модуля. К нему можно обратиться только как к атрибуту объекта модуля.

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

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

Типы пользовательских классов обычно создаются определениями классов (см. раздел Class definitions). У класса есть пространство имён, реализованное объектом-словарём. Обращения к атрибутам класса преобразуются в поиск в этом словаре: например, C.x преобразуется в C.__dict__["x"] (хотя существует ряд механизмов, позволяющих находить атрибуты другими способами). Если имя атрибута там не найдено, поиск атрибута продолжается в базовых классах. При поиске в базовых классах используется порядок разрешения методов C3, который корректно работает даже при «ромбовидном» наследовании, когда несколько путей наследования ведут к общему предку. Подробности об используемом Python порядке разрешения методов C3 можно найти в The Python 2.3 Method Resolution Order.

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

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

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

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

Атрибут

Значение

type.__name__

Имя класса. См. также: __name__ атрибуты.

type.__qualname__

Квалифицированное имя класса. См. также: атрибуты __qualname__.

type.__module__

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

type.__dict__

Прокси-отображение, предоставляющее доступное только для чтения представление пространства имён класса. См. также: атрибуты __dict__.

type.__bases__

tuple, содержащий базовые классы класса. В большинстве случаев для класса, определённого как class X(A, B, C), X.__bases__ будет в точности равен (A, B, C).

type.__base__

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

type.__doc__

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

type.__annotations__

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

Рекомендации по работе с __annotations__ см. в annotationlib. Вместо непосредственного обращения к этому атрибуту используйте annotationlib.get_annotations().

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

Непосредственное обращение к атрибуту __annotations__ объекта класса может вернуть аннотации не того класса — в частности, в определённых случаях, когда класс, его базовый класс или метакласс определены с использованием from __future__ import annotations. Подробности см. в 749.

Этот атрибут отсутствует у некоторых встроенных классов. У пользовательских классов без __annotations__ это пустой словарь.

Изменено в версии 3.14: Теперь аннотации вычисляются лениво. См. PEP 649.

type.__annotate__()

Аннотирующая функция для этого класса или None, если у класса нет аннотаций. См. также: атрибуты __annotate__.

Добавлено в версии 3.14.

type.__type_params__

tuple, содержащий параметры типов обобщённого класса.

Добавлено в версии 3.12.

type.__static_attributes__

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

Добавлено в версии 3.13.

type.__firstlineno__

Номер строки, на которой начинается определение класса, включая декораторы. Присваивание атрибуту __module__ нового значения удаляет элемент __firstlineno__ из словаря типа.

Добавлено в версии 3.13.

type.__mro__

tuple классов, просматриваемых при поиске в базовых классах в процессе разрешения методов.

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

В дополнение к специальным атрибутам, описанным выше, все классы Python также имеют следующие два метода:

type.mro()

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

type.__subclasses__()

Каждый класс хранит список слабых ссылок на свои непосредственные подклассы. Этот метод возвращает список всех таких живых ссылок. Список приведён в порядке определения. Пример:

>>> class A: pass
>>> class B(A): pass
>>> A.__subclasses__()
[<class 'B'>]

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

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

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

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

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

object.__class__

Класс, которому принадлежит экземпляр.

object.__dict__

Словарь или другой объект-отображение, используемый для хранения (доступных для записи) атрибутов объекта. Не у всех экземпляров есть атрибут __dict__; подробнее см. раздел __slots__.

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

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

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

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

file.read(size=-1, /)

Извлекает из файла до size данных. Для удобства, если size не указан или равен -1, извлекаются все доступные данные.

file.write(data, /)

Сохраняет data в файл.

file.close()

Сбрасывает все буферы и закрывает соответствующий файл.

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

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

3.2.13.1. Объекты кода

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

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

Имя функции

codeobject.co_qualname

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

Добавлено в версии 3.11.

codeobject.co_argcount

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

codeobject.co_posonlyargcount

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

codeobject.co_kwonlyargcount

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

codeobject.co_nlocals

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

codeobject.co_varnames

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

codeobject.co_cellvars

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

codeobject.co_freevars

tuple, содержащий имена свободных переменных (замыкания), на которые вложенная область видимости ссылается во внешней области видимости. См. также function.__closure__.

Примечание: ссылки на глобальные и встроенные имена не включены.

codeobject.co_code

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

codeobject.co_consts

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

codeobject.co_names

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

codeobject.co_filename

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

codeobject.co_firstlineno

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

codeobject.co_linetable

Объект bytes с закодированной информацией о расположении в исходном коде. Точный формат является деталью реализации и может меняться между версиями Python. Для доступа к информации о строках и позициях используйте поддерживаемые методы co_lines() и co_positions(). Чтобы создать изменённую копию объекта кода, используйте replace().

Добавлено в версии 3.10.

codeobject.co_stacksize

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

codeobject.co_flags

Целое число, кодирующее набор флагов для интерпретатора

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

Объявления будущих возможностей (например, from __future__ import division) также используют биты co_flags, чтобы указать, была ли включена определённая возможность при компиляции объекта кода. См. compiler_flag.

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

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

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

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

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

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

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

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

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

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

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

Добавлено в версии 3.11.

Примечание

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

codeobject.co_lines()

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

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

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

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

Выдаваемые элементы обладают следующими свойствами:

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

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

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

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

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

Добавлено в версии 3.10.

См. также

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

PEP, представивший метод co_lines().

codeobject.replace(**kwargs)

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

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

Добавлено в версии 3.8.

3.2.13.2. Объекты кадров

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

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

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

frame.f_code

Объект кода, выполняемый в этом кадре. Обращение к этому атрибуту возбуждает событие аудита object.__getattr__ с аргументами obj и "f_code".

frame.f_locals

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

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

frame.f_globals

Словарь, используемый кадром для поиска глобальных переменных

frame.f_builtins

Словарь, используемый кадром для поиска встроенных (внутренних) имён

frame.f_lasti

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

frame.f_generator

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

Добавлено в версии 3.14.

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

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

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

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

frame.clear()

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

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

Добавлено в версии 3.4.

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

3.2.13.3. Объекты трассировки

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

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

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

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

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

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

traceback.tb_frame

Указывает на исполняемый кадр текущего уровня.

Обращение к этому атрибуту возбуждает событие аудита object.__getattr__ с аргументами obj и "tb_frame".

traceback.tb_lineno

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

traceback.tb_lasti

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

Номер строки и последняя инструкция в трассировке могут отличаться от номера строки её объекта кадра, если исключение возникло в инструкции try без подходящей ветки except или с веткой finally.

traceback.tb_next

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

Изменено в версии 3.7: Этот атрибут теперь доступен для записи

3.2.13.4. Объекты срезов

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

Добавлено в версии 3.15: Тип slice() теперь поддерживает обращение к элементу. Например, slice[float] можно использовать в аннотациях типов для указания среза, содержащего объекты float.

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

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

slice.indices(self, length)

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

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

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

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

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

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

Класс может реализовывать определённые операции, вызываемые особым синтаксисом (такие как арифметические операции или обращение к элементу и срезы), определяя методы со специальными именами. Это подход Python к перегрузке операторов, позволяющий классам определять собственное поведение по отношению к операторам языка. Например, если класс определяет метод с именем __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__() будут вызваны для объектов, которые всё ещё существуют на момент завершения работы интерпретатора. weakref.finalize предоставляет простой способ зарегистрировать функцию очистки, которая будет вызвана, когда объект удаляется сборщиком мусора.

Примечание

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

Цикл ссылок может не дать счётчику ссылок объекта опуститься до нуля. В этом случае цикл будет позже обнаружен и удалён сборщиком циклического мусора. Частая причина циклов ссылок — исключение, перехваченное в локальной переменной. Тогда локальные переменные кадра ссылаются на исключение, которое ссылается на собственную трассировку, а та — на локальные переменные всех кадров, попавших в трассировку.

См. также

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

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

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

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

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

object.__repr__(self)

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

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

object.__str__(self)

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

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

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

object.__bytes__(self)

Вызывается функцией bytes для вычисления представления объекта в виде строки байтов. Метод должен возвращать объект bytes. Сам класс object этот метод не предоставляет.

object.__format__(self, format_spec)

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

Описание стандартного синтаксиса форматирования см. в Format specification mini-language.

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

Реализация по умолчанию в классе object должна получать пустую строку format_spec. Она делегирует вызов методу __str__().

Изменено в версии 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.

По умолчанию класс object предоставляет реализации, согласованные с Value comparisons: равенство проверяется по идентичности объектов, а сравнения порядка возбуждают TypeError. Каждый метод по умолчанию может выдавать эти результаты напрямую, но может также вернуть NotImplemented.

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

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

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

object.__hash__(self)

Вызывается встроенной функцией hash() и при операциях над элементами хеш-коллекций, включая set, frozenset, dict и frozendict. Метод __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__(), поскольку реализация хешируемых коллекций требует, чтобы хеш-значение ключа было неизменным (если хеш-значение объекта изменится, он окажется в неправильной хеш-корзине).

Пользовательские классы по умолчанию имеют методы __eq__() и __hash__() (унаследованные от класса object). С ними все объекты считаются неравными (кроме сравнения с самими собой), а 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). Подробности см. на https://ocert.org/advisories/ocert-2011-003.html.

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

См. также PYTHONHASHSEED.

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

object.__bool__(self)

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

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

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

object.__getattr__(self, name)

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

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

object.__getattribute__(self, name)

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

Примечание

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

Для некоторых критичных обращений к атрибутам вызывает событие аудита object.__getattr__ с аргументами obj и name.

object.__setattr__(self, name, value)

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

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

Для некоторых критичных присваиваний атрибутов вызывает событие аудита object.__setattr__ с аргументами obj, name, value.

object.__delattr__(self, name)

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

Для некоторых критичных удалений атрибутов вызывает событие аудита object.__delattr__ с аргументами obj и name.

object.__dir__(self)

Вызывается, когда функция dir() применяется к объекту. Метод должен возвращать итерируемый объект`. Функция dir() преобразует возвращённый итерируемый объект в список и сортирует его.

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

module.__getattr__()
module.__dir__()

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

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

module.__class__

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

import sys
from types import ModuleType

class VerboseModule(ModuleType):
    def __repr__(self):
        return f'Подробный {self.__name__}'

    def __setattr__(self, attr, value):
        print(f'Установка {attr}...')
        super().__setattr__(attr, value)

sys.modules[__name__].__class__ = VerboseModule

Примечание

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

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

Добавлено в версии 3.7: Атрибуты модуля __getattr__ и __dir__.

См. также

PEP 562 — __getattr__ и __dir__ в модулях

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

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

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

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

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

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

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

object.__set__(self, instance, value)

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

Обратите внимание: добавление __set__() или __delete__() превращает дескриптор в «дескриптор данных». Подробнее см. в Вызов дескрипторов.

object.__delete__(self, instance)

Вызывается, чтобы удалить атрибут в экземпляре 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

Обращение через точку вида 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__

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

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

object.__slots__

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

Замечания по использованию __slots__:

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

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

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

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

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

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

  • Если для класса, производного от встроенного типа «переменной длины», такого как int, bytes и type, определены __slots__, кроме __dict__ и __weakref__, вызывается TypeError. Для tuple это правило не действует.

  • Переменной __slots__ можно присвоить любой итерируемый объект, не являющийся строкой.

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

  • Присваивание __class__ работает, только если у обоих классов одинаковые __slots__.

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

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

Изменено в версии 3.15: Разрешено определять __dict__ и __weakref__ в __slots__ для любого класса. Разрешено определять любые __slots__ для класса, производного от tuple.

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="Брюс"):
    pass

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

Примечание

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

Добавлено в версии 3.6.

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

object.__set_name__(self, owner, name)

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

class A:
    x = C()  # Автоматически вызывает: x.__set_name__(A, 'x')

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

class A:
   pass

c = C()
A.x = c                  # Метод не вызывается
c.__set_name__(A, 'x')   # Вызываем метод вручную

Подробнее см. Создание объекта класса.

Добавлено в версии 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

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

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

  • разрешаются записи MRO;

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

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

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

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

3.3.3.2. Разрешение записей MRO

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

Базовая поддержка модуля typing и обобщённых типов.

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 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 — Новый super

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

3.3.3.7. Применение метаклассов

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

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

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

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

type.__instancecheck__(self, instance)

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

type.__subclasscheck__(self, subclass)

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

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

См. также

PEP 3119 — Введение абстрактных базовых классов

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

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

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

См. также

PEP 484 — Подсказки типов

Вводит в Python основу для аннотаций типов

Типы обобщённых псевдонимов

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

Generics, пользовательские обобщённые типы и typing.Generic

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

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

classmethod object.__class_getitem__(cls, key)

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

При определении в классе __class_getitem__() автоматически становится методом класса. Поэтому декорировать его с помощью @classmethod не нужно.

3.3.5.1. Предназначение __class_getitem__

Предназначение __class_getitem__() — позволить параметризовать обобщённые классы стандартной библиотеки во время выполнения, чтобы было проще применять к ним подсказки типов.

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

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

3.3.5.2. __class_getitem__ против __getitem__

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

Встретив выражение obj[x], интерпретатор Python решает, какой метод вызвать: __getitem__() или __class_getitem__() — примерно по такому алгоритму:

from inspect import isclass

def subscribe(obj, x):
    """Возвращает результат выражения 'obj[x]'"""

    class_of_obj = type(obj)

    # Если класс obj определяет __getitem__,
    # вызываем class_of_obj.__getitem__(obj, x)
    if hasattr(class_of_obj, '__getitem__'):
        return class_of_obj.__getitem__(obj, x)

    # Инча, если obj — класс и определяет __class_getitem__,
    # вызываем obj.__class_getitem__(x)
    elif isclass(obj) and hasattr(obj, '__class_getitem__'):
        return obj.__class_getitem__(x)

    # Иначе возбуждаем исключение
    else:
        raise TypeError(
            f"'{class_of_obj.__name__}' object is not subscriptable"
        )

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

>>> # у list метаклассом, как и у большинства классов, является класс "type":
>>> type(list)
<class 'type'>
>>> type(dict) == type(list) == type(tuple) == type(str) == type(bytes)
True
>>> # "list[int]" вызывает "list.__class_getitem__(int)"
>>> list[int]
list[int]
>>> # list.__class_getitem__ возвращает объект GenericAlias:
>>> type(list[int])
<class 'types.GenericAlias'>

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

>>> from enum import Enum
>>> class Menu(Enum):
...     """Меню завтрака"""
...     SPAM = 'спам'
...     BACON = 'бекон'
...
>>> # у классов Enum есть собственный метакласс:
>>> type(Menu)
<class 'enum.EnumMeta'>
>>> # EnumMeta определяет __getitem__,
>>> # поэтому __class_getitem__ не вызывается,
>>> # и результат не является объектом GenericAlias:
>>> Menu['SPAM']
<Menu.SPAM: 'спам'>
>>> type(Menu['SPAM'])
<enum 'Menu'>

См. также

PEP 560 — Базовая поддержка модуля typing и обобщённых типов

Вводит __class_getitem__() и описывает, когда обращение по индексатору приводит к вызову __class_getitem__() вместо __getitem__()

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

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

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

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

Следующие методы можно определить, чтобы реализовать объекты-контейнеры. Сам класс object ни один из них не предоставляет. Обычно контейнеры — это последовательности (например, списки или кортежи) или отображения (например, словари), но могут быть и контейнеры других видов. Первая группа методов служит для эмуляции либо последовательности, либо отображения. Разница в том, что для последовательности допустимые ключи — это целые числа k, для которых 0 <= k < N, где N — длина последовательности, или объекты slice, задающие диапазон элементов. Также рекомендуется, чтобы отображения предоставляли методы keys(), values(), items(), get(), clear(), setdefault(), pop(), popitem(), copy() и update(), ведущие себя аналогично соответствующим методам стандартных объектов словарей Python. Модуль collections.abc предоставляет абстрактный базовый класс MutableMapping, который помогает создать эти методы на основе базового набора __getitem__(), __setitem__(), __delitem__() и keys().

Изменяемые последовательности должны предоставлять методы append(), clear(), count(), extend(), index(), insert(), pop(), remove() и reverse(), как стандартные объекты list Python. Наконец, типы последовательностей должны реализовывать сложение (то есть конкатенацию) и умножение (то есть повторение), определяя методы __add__(), __radd__(), __iadd__(), __mul__(), __rmul__() и __imul__(), описанные ниже. Другие числовые операторы им определять не следует.

Рекомендуется, чтобы и отображения, и последовательности реализовывали метод __contains__(). Это позволит эффективно использовать оператор in. Для отображений in должен искать среди ключей, для последовательностей — среди значений. Кроме того, рекомендуется, чтобы и отображения, и последовательности реализовывали метод __iter__(). Это позволит эффективно перебирать элементы контейнера. Для отображений __iter__() должен перебирать ключи объекта, для последовательностей — значения.

object.__len__(self)

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

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

object.__length_hint__(self)

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

Добавлено в версии 3.4.

object.__getitem__(self, subscript)

Вызывается для реализации индексирования, то есть self[subscript]. Подробности о синтаксисе см. в Subscriptions and slicings.

Есть два типа встроенных объектов, которые поддерживают индексирование через __getitem__():

Если индексатор имеет неподходящий тип, __getitem__() должен вызывать TypeError. Если индексатор имеет неподходящее значение, __getitem__() должен вызывать LookupError или один из его подклассов (IndexError для последовательностей, KeyError для отображений).

Примечание

Срезы обрабатываются методами __getitem__(), __setitem__() и __delitem__(). Вызов вида

a[1:2] = b

преобразуется в

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

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

Примечание

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

Примечание

При индексировании класса вместо __getitem__() может быть вызван специальный метод класса __class_getitem__(). Подробности см. в __class_getitem__ против __getitem__.

object.__setitem__(self, key, value)

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

object.__delitem__(self, key)

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

object.__missing__(self, key)

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

object.__iter__(self)

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

object.__reversed__(self)

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

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

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

object.__contains__(self, item)

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

Для объектов, у которых метод __contains__() не определён, проверка принадлежности сначала пытается перебрать элементы через __iter__(), затем использует старый протокол итерации последовательностей через __getitem__(). См. этот раздел справочника по языку.

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 или type(y) является подклассом type(x). [5]

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

Изменено в версии 3.14: Трёхаргументная функция pow() теперь при необходимости пытается вызвать __rpow__(). Раньше этот метод вызывался только в двухаргументной pow() и в бинарном операторе возведения в степень.

Примечание

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

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 + y, рассматриваются x.__add__(y) и y.__radd__(x). В некоторых ситуациях комбинированное присваивание может приводить к неожиданным ошибкам (см. Why does a_tuple[i] += [„item“] raise an exception when the addition works?), но такое поведение на самом деле является частью модели данных.

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()). Наличие этого метода означает, что числовой объект относится к целочисленному типу. Должен возвращать целое число.

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

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

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

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

3.3.9. Менеджеры контекста инструкции with

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

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

Дополнительные сведения о менеджерах контекста см. в Context Manager Types. Сам класс object методов менеджера контекста не предоставляет.

object.__enter__(self)

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

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

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

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

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

См. также

PEP 343 — Инструкция «with»

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

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.

Добавлено в версии 3.10.

См. также

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

Спецификация инструкции match языка Python.

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

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

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

object.__buffer__(self, flags)

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

Потокобезопасность: В Python со свободной многопоточностью реализации должны управлять любым внутренним счётчиком экспорта с помощью атомарных операций. Метод должен безопасно вызываться конкурентно из нескольких потоков, а данные, лежащие в основе возвращаемого буфера, должны оставаться действительными, пока не завершится соответствующий вызов __release_buffer__(). Подробности см. в Thread safety for memoryview objects.

object.__release_buffer__(self, buffer)

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

Потокобезопасность: В Python со свободной многопоточностью любое уменьшение счётчика экспорта должно использовать атомарные операции. Освобождение ресурсов должно быть потокобезопасным, так как последнее освобождение может оказаться в гонке с конкурентными освобождениями из других потоков.

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

Добавлено в версии 3.12.

См. также

PEP 688 — Обеспечение доступа к протоколу буфера из Python

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

collections.abc.Buffer

Абстрактный базовый класс для буферных типов.

3.3.12. Аннотации

Функции, классы и модули могут содержать аннотации — способ связать информацию (обычно подсказки типов) с символом.

object.__annotations__

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

Изменено в версии 3.14: Аннотации теперь вычисляются лениво.

object.__annotate__(format)

Аннотирующая функция. Возвращает новый словарь, сопоставляющий имена атрибутов или параметров с их значениями аннотаций.

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

Если аннотирующая функция не поддерживает запрошенный формат, она должна возбудить NotImplementedError. Аннотирующие функции обязаны всегда поддерживать формат VALUE: при вызове с этим форматом они не должны возбуждать NotImplementedError().

При вызове с форматом VALUE аннотирующая функция может возбудить NameError. При запросе любого другого формата она не должна возбуждать NameError.

Если у объекта нет аннотаций, его атрибуту __annotate__ лучше присвоить значение None вместо функции, возвращающей пустой словарь. Удалить этот атрибут нельзя.

Добавлено в версии 3.14.

См. также

PEP 649 — Отложенное вычисление аннотаций с помощью дескрипторов

Представляет ленивое вычисление аннотаций и функцию __annotate__.

3.3.13. Поиск специальных методов

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

>>> 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("Вызван getattribute метакласса")
...         return type.__getattribute__(*args)
...
>>> class C(object, metaclass=Meta):
...     def __len__(self):
...         return 10
...     def __getattribute__(*args):
...         print("Вызван getattribute класса")
...         return object.__getattribute__(*args)
...
>>> c = C()
>>> c.__len__()                 # Явный поиск через экземпляр
Class getattribute invoked
10
>>> type(c).__len__(c)          # Явный поиск через тип
Metaclass getattribute invoked
10
>>> len(c)                      # Неявный поиск
10

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

3.4. Сопрограммы

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

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

Примечание

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

object.__await__(self)

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

Примечание

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

Добавлено в версии 3.5.

См. также

Дополнительную информацию об ожидаемых объектах см. в PEP 492.

3.4.2. Объекты сопрограмм

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

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

Сопрограммы являются обобщёнными по типам выдаваемых, принимаемых и возвращаемых ими значений соответственно.

Изменено в версии 3.5.2: Повторное ожидание сопрограммы возбуждает RuntimeError.

coroutine.send(value)

Запускает или возобновляет выполнение сопрограммы. Если value равно None, это эквивалентно продвижению итератора, возвращённого __await__(). Если value не равно 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 в точке приостановки, из-за чего сопрограмма немедленно выполняет очистку. Наконец, сопрограмма помечается как завершившая выполнение, даже если она никогда не запускалась.

Перед уничтожением объекты сопрограмм автоматически закрываются описанным выше способом.

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

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

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

Сам класс object этих методов не предоставляет.

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

Добавлено в версии 3.5.

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

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

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

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

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

Сам класс object этих методов не предоставляет.

object.__aenter__(self)

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

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

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

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

class AsyncContextManager:
    async def __aenter__(self):
        await log('вход в контекст')

    async def __aexit__(self, exc_type, exc, tb):
        await log('выход из контекста')

Добавлено в версии 3.5.

Примечания