Spec-Zone.ru › Python 3.14

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

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

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

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

Особенность реализации CPython: В CPython id(x) — это адрес в памяти, по которому хранится x.

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

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

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

Особенность реализации CPython: В настоящее время 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. Числовые методы и методы расширенного сравнения должны возвращать это значение, если они не реализуют операцию для переданных операндов. (Затем интерпретатор попробует выполнить отражённую операцию или применит другой запасной вариант — в зависимости от оператора.) Это значение не следует использовать в логическом контексте.

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

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

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

3.2.3. Многоточие

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

3.2.4. numbers.Number

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

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

  • Это допустимые числовые литералы, которые при передаче конструктору соответствующего класса создают объект со значением исходного числа.
  • По возможности представление использует основание 10.
  • Начальные нули не отображаются, за исключением, возможно, одного нуля перед десятичной точкой.
  • Конечные нули не отображаются, за исключением, возможно, одного нуля после десятичной точки.
  • Знак отображается, только если число отрицательное.

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

3.2.4.1. numbers.Integral

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

Примечание

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

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

Integers (int)

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

Booleans (bool)

Они представляют логические значения False и True. Объекты 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, срез обрабатывается так, как если бы start был равен нулю. Если stop отсутствует или равен None, срез обрабатывается так, как если бы stop был равен длине последовательности.

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

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

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

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

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

Строки

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

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

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

Кортежи

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

Байты

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

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

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

Примечание

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

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

Списки

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

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

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

3.2.6. Типы множеств

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

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

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

Множества

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

Неизменяемые множества

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

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

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

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

3.2.7.1. Словари

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

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

Словари изменяемы; их можно создавать с помощью обозначения {} (см. раздел Создание словарей).

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

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

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

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

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

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

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

Атрибут

Значение

function.__builtins__

Ссылка на dictionary, в котором хранится пространство имён встроенных объектов функции.

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

function.__globals__

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

function.__closure__

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

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

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

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

Атрибут

Значение

function.__doc__

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

function.__name__

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

function.__qualname__

Полное имя функции. См. также: __qualname__ attributes.

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

function.__module__

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

function.__defaults__

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

function.__code__

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

function.__dict__

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

function.__annotations__

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

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

function.__annotate__

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

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

function.__kwdefaults__

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

function.__type_params__

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

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

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

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

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

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

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

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

method.__self__

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

method.__func__

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

method.__doc__

Документация метода (та же, что и у method.__func__.__doc__). string, если у исходной функции была строка документации, иначе 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), называется функцией-генератором. При вызове такая функция всегда возвращает объект итератора, с помощью которого можно выполнить тело функции: вызов метода 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. (Семантика этого атрибута такая же, как у other instance methods.)

3.2.8.8. Классы

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

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

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

3.2.9. Модули

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

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

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

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

Для динамического создания модуля без использования системы импорта рекомендуется применять importlib.util.module_from_spec(): эта функция задаёт соответствующие значения различных атрибутов, управляемых системой импорта. Модули также можно создавать напрямую с помощью конструктора types.ModuleType, однако этот способ более подвержен ошибкам: при его использовании большинство атрибутов нужно задавать объекту модуля вручную после его создания.

Внимание

За исключением __name__, настоятельно рекомендуется полагаться на __spec__ и его атрибуты, а не на другие отдельные атрибуты, перечисленные в этом подразделе. Обратите внимание: изменение атрибута у __spec__ не обновит соответствующий атрибут самого модуля:

>>> import typing
>>> typing.__name__, typing.__spec__.name
('typing', 'typing')
>>> typing.__spec__.name = 'spelling'
>>> typing.__name__, typing.__spec__.name
('typing', 'spelling')
>>> typing.__name__ = 'keyboard_smashing'
>>> typing.__name__, typing.__spec__.name
('keyboard_smashing', 'spelling')
module.__name__

Имя, используемое для уникальной идентификации модуля в системе импорта. Для модуля, выполняемого напрямую, этому атрибуту будет присвоено значение "__main__".

Этому атрибуту должно быть присвоено полное имя модуля. Предполагается, что оно совпадает со значением module.__spec__.name.

module.__spec__

Запись о состоянии модуля, связанном с системой импорта.

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

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

module.__package__

Пакет, к которому относится модуль.

Если модуль является модулем верхнего уровня (то есть не входит ни в какой конкретный пакет), атрибуту следует присвоить значение '' (пустую строку). В противном случае ему следует присвоить имя пакета модуля (которое может совпадать с module.__name__, если сам модуль является пакетом). Подробнее см. в PEP 366.

Для вычисления явных относительных импортов главных модулей вместо __name__ используется этот атрибут. Для модулей, созданных динамически с помощью конструктора types.ModuleType, по умолчанию используется значение None; вместо этого используйте importlib.util.module_from_spec(), чтобы атрибуту было присвоено значение типа str.

Настоятельно рекомендуется использовать module.__spec__.parent вместо module.__package__. Теперь __package__ используется только как резервное значение, если __spec__.parent не задан; этот резервный механизм объявлен устаревшим.

Изменено в версии 3.4: Теперь для модулей, созданных динамически с помощью конструктора types.ModuleType, по умолчанию этому атрибуту присваивается значение None. Ранее атрибут был необязательным.

Изменено в версии 3.6: Ожидается, что значение __package__ совпадает со значением __spec__.parent. Теперь __package__ используется только как резервное значение при разрешении импорта, если __spec__.parent не определён.

Изменено в версии 3.10: Если при разрешении импорта используется резервное значение __package__ вместо __spec__.parent, возникает исключение ImportWarning.

Изменено в версии 3.12: При использовании резервного значения __package__ во время разрешения импорта возникает исключение DeprecationWarning вместо ImportWarning.

Устарело начиная с версии 3.13; будет удалено в версии 3.15: Система импорта и стандартная библиотека перестанут задавать __package__ или учитывать его.

module.__loader__

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

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

Для модулей, созданных динамически с помощью конструктора types.ModuleType, для __loader__ по умолчанию используется значение None; вместо этого используйте importlib.util.module_from_spec(), чтобы атрибуту было присвоено значение объекта загрузчика.

Настоятельно рекомендуется использовать module.__spec__.loader вместо module.__loader__.

Изменено в версии 3.4: Теперь для модулей, созданных динамически с помощью конструктора types.ModuleType, для этого атрибута по умолчанию используется значение None. Ранее атрибут был необязательным.

Устарело начиная с версии 3.12; будет удалено в версии 3.16: Присваивание модулю значения __loader__ без присваивания значения __spec__.loader объявлено устаревшим. В Python 3.16 система импорта и стандартная библиотека перестанут задавать __loader__ или учитывать его.

module.__path__

(Возможно, пустая) последовательность строк, перечисляющих расположения, в которых находятся подмодули пакета. У модулей, не являющихся пакетами, не должно быть атрибута __path__. Подробнее см. в разделе Атрибуты __path__ у модулей.

Настоятельно рекомендуется использовать module.__spec__.submodule_search_locations вместо module.__path__.

module.__file__
module.__cached__

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

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

Если задан __file__, может быть задан и атрибут __cached__, содержащий путь к скомпилированной версии кода (например, к файлу с байт-кодом). Для задания этого атрибута файл не обязан существовать; путь может просто указывать на место, где скомпилированный файл находился бы (см. PEP 3147).

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

Настоятельно рекомендуется использовать module.__spec__.cached вместо module.__cached__.

Устарело начиная с версии 3.13; будет удалено в версии 3.15: Присваивание модулю значения __cached__ без присваивания значения __spec__.cached объявлено устаревшим. В Python 3.15 система импорта и стандартная библиотека перестанут задавать __cached__ или учитывать его.

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

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

module.__doc__

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

module.__annotations__

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

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

module.__annotate__

Функция аннотирования этого модуля или None, если у модуля нет аннотаций. См. также атрибуты __annotate__.

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

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

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

module.__dict__

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

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

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

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

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

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

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

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

Атрибут

Значение

type.__name__

Имя класса. См. также: __name__ attributes.

type.__qualname__

Полное имя класса. См. также: __qualname__ attributes.

type.__module__

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

type.__dict__

Объект mapping proxy, предоставляющий доступ только для чтения к пространству имён класса. См. также: __dict__ attributes.

type.__bases__

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

type.__base__

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

type.__doc__

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

type.__annotations__

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

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

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

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

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

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

type.__annotate__()

Функция аннотирования этого класса или None, если у класса нет аннотаций. См. также: __annotate__ attributes.

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

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

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

codeobject.co_stacksize

Необходимый размер стека для объекта кода

codeobject.co_flags

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

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

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

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

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

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

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

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

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

  • Запуск интерпретатора с параметром -X no_debug_ranges.
  • Загрузка файла pyc, скомпилированного с параметром -X no_debug_ranges.
  • Кортежи позиций, соответствующие искусственным инструкциям.
  • Номера строк и столбцов, которые нельзя представить из-за ограничений, специфичных для реализации.

В таких случаях некоторые или все элементы кортежа могут быть равны None.

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

Примечание

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

codeobject.co_lines()

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

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

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

  • Первый выдаваемый диапазон будет иметь start, равный 0.
  • Диапазоны (start, end) будут неубывающими и последовательными. То есть для любой пары tuple значение 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.

Для неявно созданных трассировок стека при разматывании стека выполнения в ходе поиска обработчика исключения на каждом пройденном уровне перед текущей трассировкой стека вставляется объект трассировки стека. При входе в обработчик исключения трассировка стека становится доступна программе. (См. раздел Оператор try.) Она доступна как третий элемент кортежа, возвращаемого 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().

Специальные атрибуты только для чтения: 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 достигает нуля.

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

См. также

Документацию модуля 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__(), однако большинство классов либо делегируют форматирование одному из встроенных типов, либо используют похожий синтаксис параметров форматирования.

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

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

В реализацию по умолчанию класса 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 предоставляет реализации, соответствующие разделу Сравнение значений: равенство определяется идентичностью объектов, а сравнение порядка вызывает TypeError. Каждый метод по умолчанию может напрямую возвращать такие результаты, но также может вернуть NotImplemented.

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

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

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

object.__hash__(self)

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

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

Примечание

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

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

Пользовательские классы по умолчанию имеют методы __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.

Это предназначено для защиты от отказа в обслуживании, вызванного тщательно подобранными входными данными, эксплуатирующими наихудшую производительность вставки в dict со сложностью 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'Verbose {self.__name__}'

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

sys.modules[__name__].__class__ = VerboseModule

Примечание

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

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

Добавлено в версии 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 поддерживают это требование; однако некоторые сторонние инструменты могут содержать дескрипторы, которым требуются оба аргумента. Собственная реализация Python для __getattribute__() всегда передаёт оба аргумента независимо от того, обязательны ли они.

object.__set__(self, instance, value)

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

Обратите внимание: добавление __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__, не поддерживают weak references для своих экземпляров. Если необходима поддержка слабых ссылок, добавьте '__weakref__' в последовательность строк в объявлении __slots__.
  • __slots__ реализуется на уровне класса путём создания дескрипторов для каждого имени переменной. В результате атрибуты класса нельзя использовать для задания значений по умолчанию для переменных экземпляра, определённых в __slots__: атрибут класса в противном случае перезаписал бы присваивание через дескриптор.
  • Действие объявления __slots__ не ограничивается классом, в котором оно определено. Объявленные в родительских классах __slots__ доступны дочерним классам. Однако экземпляры дочернего подкласса будут иметь __dict__ и __weakref__, если подкласс также не определяет __slots__ (который должен содержать только имена дополнительных слотов).
  • Если класс определяет слот, уже определённый в базовом классе, переменная экземпляра, определённая слотом базового класса, становится недоступной (кроме случая, когда её дескриптор напрямую получен из базового класса). Это делает значение программы неопределённым. В будущем может быть добавлена проверка, предотвращающая такую ситуацию.
  • Если для класса, производного от "variable-length" built-in type, определены непустые __slots__, будет вызвано исключение TypeError. К таким типам относятся int, bytes и tuple.
  • В качестве значения __slots__ можно использовать любой итерируемый объект, кроме строки.
  • Если для присваивания __slots__ используется dictionary, его ключи будут использоваться в качестве имён слотов. Значения словаря можно использовать для указания строк документации отдельных атрибутов; их распознаёт inspect.getdoc(), и они отображаются в выводе help().
  • Присваивание __class__ работает только в том случае, если у обоих классов одинаковые __slots__.
  • Можно использовать множественное наследование с несколькими родительскими классами, содержащими слоты, но только у одного родителя могут быть атрибуты, созданные слотами (у остальных базовых классов должны быть пустые наборы слотов). Нарушение этого правила вызывает TypeError.
  • Если для __slots__ используется итератор, для каждого значения итератора создаётся дескриптор. Однако атрибут __slots__ будет пустым итератором.

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

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

classmethod object.__init_subclass__(cls)

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

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

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

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

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

Примечание

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

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

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

object.__set_name__(self, owner, name)

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

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

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

class A:
   pass

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

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

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

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

type.__subclasscheck__(self, subclass)

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

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

См. также

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

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

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

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

См. также

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

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

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

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

Generics, user-defined generics and 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):
    """Return the result of the expression 'obj[x]'"""

    class_of_obj = type(obj)

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

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

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

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

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

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

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

См. также

PEP 560 — Базовая поддержка модуля 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. Контейнеры обычно являются последовательностями (например, lists или tuples) либо отображениями (например, словари), но могут представлять и другие типы контейнеров. Первый набор методов используется для эмуляции последовательности или отображения; различие состоит в том, что для последовательности допустимыми ключами должны быть целые числа k, для которых 0 <= k < N, где N — длина последовательности, или объекты slice, задающие диапазон элементов. Также рекомендуется, чтобы отображения предоставляли методы keys(), values(), items(), get(), clear(), setdefault(), pop(), popitem(), copy() и update(), работающие аналогично соответствующим методам стандартных объектов Python dictionary. Модуль collections.abc предоставляет MutableMapping — абстрактный базовый класс, который помогает создать эти методы на основе набора методов __getitem__(), __setitem__(), __delitem__() и keys().

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

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

object.__len__(self)

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

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

object.__length_hint__(self)

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

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

object.__getitem__(self, subscript)

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

Существуют два типа встроенных объектов, поддерживающих индексацию с помощью __getitem__():

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

Если индекс имеет неподходящий тип, __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__(). Этот метод следует реализовывать для отображений только в том случае, если объекты поддерживают изменение значений для ключей или добавление новых ключей, а для последовательностей — если элементы можно заменять. Для недопустимых значений ключа должны вызываться те же исключения, что и для метода __getitem__().

object.__delitem__(self, key)

Вызывается для реализации удаления self[key]. См. примечание к __getitem__(). Этот метод следует реализовывать для отображений только в том случае, если объекты поддерживают удаление ключей, а для последовательностей — если элементы можно удалять из последовательности. Для недопустимых значений ключа должны вызываться те же исключения, что и для метода __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]

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

Изменено в версии 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.__add__(y) и y.__radd__(x), как при вычислении x + y. В некоторых ситуациях расширенное присваивание может приводить к неожиданным ошибкам (см. раздел Почему a_tuple[i] += [‘item’] вызывает исключение, если сложение выполняется успешно?), однако такое поведение является частью модели данных.

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

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

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

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

object.__index__(self)

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

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

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

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

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

3.3.9. Менеджеры контекста оператора with

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

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

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

object.__enter__(self)

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

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

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

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

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

См. также

PEP 343 — оператор «with»

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

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

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

object.__match_args__

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

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

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

См. также

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

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

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

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

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

object.__buffer__(self, flags)

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

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

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)

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

Принимает параметр 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("Metaclass getattribute invoked")
...         return type.__getattribute__(*args)
...
>>> class C(object, metaclass=Meta):
...     def __len__(self):
...         return 10
...     def __getattribute__(*args):
...         print("Class getattribute invoked")
...         return object.__getattribute__(*args)
...
>>> c = C()
>>> c.__len__()                 # Explicit lookup via instance
Class getattribute invoked
10
>>> type(c).__len__(c)          # Explicit lookup via type
Metaclass getattribute invoked
10
>>> len(c)                      # Implicit lookup
10

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

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

3.4.1. Объекты, ожидающие завершения

Объект, ожидающий завершения, обычно реализует метод __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.

У сопрограмм также есть перечисленные ниже методы, аналогичные методам генераторов (см. раздел Методы итераторов-генераторов). Однако, в отличие от генераторов, сопрограммы не поддерживают непосредственный перебор.

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

Изменено в версии 3.5.2: Повторный вызов await для одной и той же сопрограммы вызывает исключение 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('entering context')

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

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

Сноски

[1]

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

[2]

Методы __hash__(), __iter__(), __reversed__(), __contains__(), __class_getitem__() и __fspath__() обрабатываются особым образом. Другие методы также вызовут исключение TypeError, но могут сделать это, полагаясь на то, что None не является вызываемым объектом.

[3]

Здесь «не поддерживает» означает, что у класса нет такого метода либо метод возвращает NotImplemented. Не устанавливайте метод в значение None, если хотите обеспечить переход к отражённому методу правого операнда: это даст обратный эффект и явно запретит такой переход.

[4]

Для операндов одного типа предполагается, что если неотражённый метод (например, __add__()) завершается неудачей, операция не поддерживается; поэтому отражённый метод не вызывается.

[5]

Если тип правого операнда является подклассом типа левого операнда, приоритет отражённого метода позволяет подклассам переопределять операции предков.

© 2001 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.14/reference/datamodel.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API