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 — единственные булевы объекты. Булев тип является подтипом целочисленного типа, и булевы значения ведут себя как значения 0 и 1 соответственно практически во всех контекстах, исключение составляет преобразование в строку, где возвращаются строки "False" или "True" соответственно.

3.2.4.2. numbers.Real (float)

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

3.2.4.3. numbers.Complex (complex)

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

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

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

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

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

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

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

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

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

Строки

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

Кортежи

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

Объекты типа bytes

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

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

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

Примечание

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

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

Списки

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

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

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

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

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

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

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

Множества

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

Замороженные множества

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

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

Они представляют собой конечные множества объектов, индексированные произвольными множествами индексов. Нотация подстановки a[k] выбирает элемент, индексированный k из отображения a; это можно использовать в выражениях и в качестве цели присваивания или операторов 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__ асинхронного итератора вернёт awaitable, ожидание которого выполнит функцию до тех пор, пока она не предоставит значение с помощью выражения 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__ для вычисления явных относительных импортов для основных модулей. Он имеет значение по умолчанию None для динамически созданных модулей с помощью конструктора types.ModuleType; используйте importlib.util.module_from_spec() для обеспечения установки атрибута в str.

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

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

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

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

Изменено в версии 3.12: Вместо ImportWarning поднимается DeprecationWarning, если при разрешении импорта используется резервный вариант __package__.

Устарело начиная с версии 3.13, будет удалено в версии 3.15: __package__ больше не будет устанавливаться или учитываться системой импорта или стандартной библиотекой.

module.__loader__

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

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

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

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

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

Устарело начиная с версии 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 можно найти в Порядок разрешения методов 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. Объекты ввода-вывода (также известные как файловые объекты)

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

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

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

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

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

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

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

Имя функции

codeobject.co_qualname

Полностью квалифицированное имя функции

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

codeobject.co_argcount

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

codeobject.co_posonlyargcount

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

codeobject.co_kwonlyargcount

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

codeobject.co_nlocals

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

codeobject.co_varnames

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

codeobject.co_cellvars

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

codeobject.co_freevars

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

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

codeobject.co_code

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

codeobject.co_consts

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

codeobject.co_names

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

codeobject.co_filename

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

codeobject.co_firstlineno

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

codeobject.co_lnotab

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

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

codeobject.co_stacksize

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

codeobject.co_flags

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

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

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

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

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

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

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

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

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

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

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

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

Примечание

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

codeobject.co_lines()

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

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

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

  • Первый возвращаемый диапазон будет иметь start 0.
  • Возвращаемые диапазоны будут не убывающими и последовательными. То есть для любой пары кортежей, start второго будет равно end первого.
  • Ни один диапазон не будет обратным: end >= start для всех троек.
  • Последний кортеж, возвращённый итератором, будет иметь 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__().

END_OF_DOCUMENT_MARKER
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, потому что имя не является атрибутом экземпляра или атрибутом в дереве классов для self; либо __get__() свойства имя вызывает 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)

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

Если __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. Настройка доступа к атрибутам модуля

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

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

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

import sys
from types import ModuleType

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

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

sys.modules[__name__].__class__ = VerboseModule

Примечание

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

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

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

См. также

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

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

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

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

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

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

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

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

object.__set__(self, instance, value)

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

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

object.__delete__(self, instance)

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

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

object.__objclass__

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

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

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

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

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

Точка отсчёта для вызова дескрипторов — это привязка a.x. Как собираются аргументы, зависит от a:

Прямой вызов

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

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

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

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

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

Привязка super

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

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

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

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

3.3.2.4. __slots__

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

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

object.__slots__

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

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

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

Основная поддержка модуля типов и типов дженериков.

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__ для правильной инициализации класса. Отсутствие этого приведет к ошибке RuntimeError в Python 3.8.

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

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

Если определен в классе, __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 будет возбуждаться для недопустимых индексов, чтобы обеспечить надлежащее обнаружение конца последовательности.

Примечание

При индексировании класса может быть вызван специальный метод класса __class_getitem__() вместо __getitem__(). См. __class_getitem__ versus __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(). Если параметр ndigits не передан функции __round__(), все эти методы должны возвращать значение объекта, усеченного до целочисленного значения (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

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

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

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

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

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

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

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

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

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

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

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

3.4. Корутины

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

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

Примечание

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

object.__await__(self)

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

Примечание

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

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

См. также

PEP 492 для дополнительной информации об объектах, поддерживающих ожидание.

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

Объекты корутин являются awaitable объектами. Выполнение корутины может быть контролируемо вызовом метода __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)

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

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

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

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

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

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

object.__aenter__(self)

Семантически подобен __enter__(), единственное отличие заключается в том, что он должен возвращать awaitable.

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

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

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

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–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.13/reference/datamodel.html

Spec-Zone.ru

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