Spec-Zone.ru › Python 3.13

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

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 в логическом контексте считается устаревшим. Хотя сейчас оно вычисляется как истина, будет выдано предупреждение DeprecationWarning. В будущей версии Python это приведёт к исключению TypeError.

3.2.3. Ellipsis

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

3.2.4. numbers.Number

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

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

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

В 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 до n-1. Элемент i последовательности a выбирается с помощью a[i]. Некоторые последовательности, в том числе встроенные, обрабатывают отрицательные индексы, прибавляя к ним длину последовательности. Например, a[-2] равно a[n-2] — предпоследнему элементу последовательности a длиной n.

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

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

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

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

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

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

Строки

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

Кортежи

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

Байты

Объект bytes — это неизменяемый массив. Его элементы — 8-битные байты, представленные целыми числами из диапазона от 0 до 256 (не включая 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.__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' — аннотация возвращаемого значения, если она задана. См. также: Рекомендации по использованию аннотаций.

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: Вызывается ImportWarning, если при разрешении импорта используется резервное значение __package__ вместо __spec__.parent.

Изменено в версии 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__ см. в разделе Рекомендации по работе с аннотациями.

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

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

module.__dict__

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

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

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

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

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

type.__annotations__

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

Внимание

Прямое обращение к атрибуту __annotations__ объекта класса может привести к некорректным результатам при наличии метаклассов. Кроме того, у некоторых классов этот атрибут может отсутствовать. Для безопасного получения аннотаций класса используйте inspect.get_annotations().

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

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

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_consts — это строка документации функции или None, если она не определена.

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

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

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). Подробности см. по адресу http://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 в __dict__ модуля выполняется поиск __getattr__. Если он найден, то вызывается с именем атрибута, а результат возвращается.

Функция __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 — Module __getattr__ and __dir__

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

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

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

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

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

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

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

object.__set__(self, instance, value)

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

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

object.__delete__(self, instance)

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

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

object.__objclass__

Модуль inspect трактует атрибут __objclass__ как указание на класс, в котором был определён этот объект (правильная установка этого атрибута может помочь при интроспекции динамических атрибутов класса во время выполнения). Для вызываемых объектов он может указывать, что в качестве первого позиционного аргумента ожидается или требуется экземпляр заданного типа (или его подкласса) (например, 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, например int, bytes или tuple, определён непустой __slots__, будет вызвано исключение TypeError.
  • В __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(), count(), index(), extend(), insert(), pop(), remove(), reverse() и sort(), как у стандартных списков 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.

Примечание

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

a[1:2] = b

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

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

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

object.__getitem__(self, key)

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

Примечание

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

Примечание

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

object.__setitem__(self, key, value)

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

object.__delitem__(self, key)

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

object.__missing__(self, key)

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

object.__iter__(self)

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

object.__reversed__(self)

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

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

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

object.__contains__(self, item)

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

Для объектов, у которых не определён метод __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.

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

Примечание

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

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

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

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

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

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

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

object.__index__(self)

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

Если методы __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).

Встроенная функция int() использует __trunc__() в качестве запасного варианта, если не определён ни __int__(), ни __index__().

Изменено в версии 3.11: Передача вызова 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.

object.__release_buffer__(self, buffer)

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

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

См. также

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

Вводит методы Python __buffer__ и __release_buffer__.

collections.abc.Buffer

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

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

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

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

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

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

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

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

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

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

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

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

3.4.1. Объекты, допускающие ожидание

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

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

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

coroutine.send(value)

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

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

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

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

coroutine.close()

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

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

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

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

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

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

object.__aiter__(self)

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

object.__anext__(self)

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

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

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

    def __aiter__(self):
        return self

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

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

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

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

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

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

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

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

object.__aenter__(self)

Семантически аналогичен методу __enter__(); единственное отличие состоит в том, что он должен возвращать объект, допускающий ожидание.

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

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

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

class AsyncContextManager:
    async def __aenter__(self):
        await log('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__(), завершается неудачей, то операция в целом не поддерживается; именно поэтому отражённый метод не вызывается.

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

Spec-Zone.ru

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