Модель данных
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 могут или не могут ссылаться на один и тот же объект со значением один, в зависимости от реализации, но после c = []; d =
[], c и d гарантированно ссылаются на два различных, уникальных, только что созданных пустых списка. (Обратите внимание, что c = d = [] присваивает один и тот же объект как c, так и d.)
3.2. Иерархия стандартных типов
Ниже приведён список встроенных типов Python. Дополнительные типы могут быть определены модулями расширения (написанными на C, Java или других языках в зависимости от реализации). В будущих версиях Python могут быть добавлены типы в иерархию (например, рациональные числа, эффективно хранящиеся массивы целых чисел и т. д.), хотя такие добавления часто будут предоставляться через стандартную библиотеку.
В некоторых описаниях типов ниже содержится параграф со списком «специальных атрибутов». Это атрибуты, предоставляющие доступ к реализации и не предназначенные для общего использования. Их определение может измениться в будущем.
- None
-
Этот тип имеет единственное значение. Существует единственный объект с этим значением. К этому объекту можно обратиться через встроенное имя
None. Он используется для обозначения отсутствия значения во многих ситуациях, например, он возвращается из функций, которые не явно ничего не возвращают. Его истинное значение — ложь. - NotImplemented
-
Этот тип имеет единственное значение. Существует единственный объект с этим значением. К этому объекту можно обратиться через встроенное имя
NotImplemented. Методы чисел и методы сравнения должны возвращать это значение, если они не реализуют операцию для заданных операндов. (Тогда интерпретатор попытается выполнить отражённую операцию или использовать какой-либо другой способ обработки в зависимости от оператора.) Его истинное значение — истина.См. Реализация арифметических операций для получения дополнительной информации.
- Ellipsis
-
Этот тип имеет единственное значение. Существует единственный объект с этим значением. К этому объекту можно обратиться через литерал
...или встроенное имяEllipsis. Его истинное значение — истина. -
numbers.Number -
Эти объекты создаются числовыми литералами и возвращаются в качестве результатов арифметическими операторами и встроенными арифметическими функциями. Числовые объекты неизменяемы; однажды созданные, их значение никогда не меняется. Числа Python, конечно, тесно связаны с математическими числами, но подчиняются ограничениям представления чисел в компьютерах.
Строковые представления числовых классов, вычисляемые с помощью
__repr__()и__str__(), обладают следующими свойствами:- Они являются допустимыми числовыми литералами, которые, когда передаются в конструктор своего класса, производят объект, имеющий значение исходного числового значения.
- Представление находится в десятичной системе счисления, когда это возможно.
- Ведущие нули, возможно, за исключением одного нуля перед десятичной точкой, не отображаются.
- Замыкающие нули, возможно, за исключением одного нуля после десятичной точки, не отображаются.
- Знак отображается только в том случае, если число отрицательное.
Python различает целые числа, числа с плавающей запятой и комплексные числа:
-
numbers.Integral -
Они представляют элементы математического множества целых чисел (положительные и отрицательные).
Существует два типа целых чисел:
-
Integers (int) -
Они представляют числа в неограниченном диапазоне, ограниченном только доступной (виртуальной) памятью. Для целей операций сдвига и маски предполагается двоичное представление, а отрицательные числа представлены вариантом дополнительного кода, который даёт иллюзию бесконечной последовательности знаковых битов, простирающихся влево.
-
Booleans (bool) -
Они представляют логические значения False и True. Два объекта, представляющие значения
FalseиTrueявляются единственными объектами типа Boolean. Тип Boolean является подтипом типа integer, и значения Boolean ведут себя как значения 0 и 1 соответственно почти во всех контекстах, исключением является то, что при преобразовании в строку возвращаются строки"False"или"True"соответственно.
Правила представления целых чисел предназначены для предоставления наиболее осмысленной интерпретации операций сдвига и маскирования, включающих отрицательные целые числа.
-
-
numbers.Real (float) -
Они представляют числа с плавающей запятой двойной точности на уровне машины. Вы зависите от архитектуры базовой машины (и реализации на C или Java) в отношении допустимого диапазона и обработки переполнения. Python не поддерживает числа с плавающей запятой одинарной точности; экономия процессора и памяти, которая обычно является причиной использования таких чисел, ничтожна по сравнению с накладными расходами на использование объектов в Python, поэтому нет причин усложнять язык двумя типами чисел с плавающей запятой.
-
numbers.Complex (complex) -
Они представляют комплексные числа как пару чисел с плавающей запятой двойной точности на уровне машины. Применимы те же оговорки, что и для чисел с плавающей запятой. Действительную и мнимую части комплексного числа
zможно получить через только для чтения атрибутыz.realиz.imag.
- Последовательности
-
Они представляют конечные упорядоченные множества, индексируемые неотрицательными числами. Встроенная функция
len()возвращает количество элементов в последовательности. Когда длина последовательности равна n, множество индексов содержит числа 0, 1, …, n-1. Элемент i последовательности a выбирается с помощьюa[i].Последовательности также поддерживают слайсинг:
a[i:j]выбирает все элементы с индексом k, такие что i<=k<j. При использовании в качестве выражения срез — это последовательность того же типа. Это подразумевает, что множество индексов переиндексировано так, что оно начинается с 0.Некоторые последовательности также поддерживают «расширенный слайсинг» с третьим параметром «шаг»:
a[i:j:k]выбирает все элементы a с индексом x, гдеx = i + n*k, n>=0и i<=x<j.Последовательности различаются по своей изменяемости:
- Неизменяемые последовательности
-
Объект неизменяемого типа последовательности не может измениться после его создания. (Если объект содержит ссылки на другие объекты, эти другие объекты могут быть изменяемыми и могут быть изменены; однако коллекция объектов, напрямую ссылающихся на неизменяемый объект, не может измениться.)
Следующие типы являются неизменяемыми последовательностями:
- Строки
-
Строка — это последовательность значений, представляющих точки кода Юникода. Все точки кода в диапазоне
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. Литералы байтов (например,
b'abc') и встроенный конструкторbytes()можно использовать для создания объектов bytes. Кроме того, объекты bytes можно декодировать в строки с помощью методаdecode().
- Изменяемые последовательности
-
Изменяемые последовательности могут быть изменены после создания. Нотации подстановки и срезов могут использоваться в качестве целевых значений для присваивания и операторов
del(удаления).В настоящее время существуют два встроенных типа изменяемых последовательностей:
- Списки
-
Элементами списка являются произвольные объекты Python. Списки формируются путём размещения списка выражений, разделённых запятыми, в квадратных скобках. (Обратите внимание, что для формирования списков длины 0 или 1 нет необходимости в специальных случаях.)
- Массивы байтов
-
Объект bytearray — это изменяемый массив. Они создаются встроенным конструктором
bytearray(). Помимо изменяемости (и, следовательно, неиспользуемости в качестве ключей словарей), массивы байтов в остальном предоставляют тот же интерфейс и функциональность, что и неизменяемые объектыbytes.
Модуль расширения
arrayпредоставляет дополнительный пример типа изменяемой последовательности, а также модульcollections.
- Типы множеств
-
Эти объекты представляют неупорядоченные, конечные множества уникальных неизменяемых объектов. Поэтому к ним нельзя обратиться по индексу. Однако по ним можно итерироваться, и встроенная функция
len()возвращает количество элементов в множестве. Типичные применения множеств — быстрое тестирование на принадлежность, удаление дубликатов из последовательности и вычисление математических операций, таких как пересечение, объединение, разность и симметрическая разность.Для элементов множества применяются те же правила неизменяемости, что и для ключей словарей. Обратите внимание, что числовые типы подчиняются стандартным правилам сравнения чисел: если два числа равны (например,
1и1.0), то только одно из них может содержаться в множестве.В настоящее время существуют два встроенных типа множеств:
- Множества
-
Они представляют собой изменяемое множество. Они создаются встроенным конструктором
set()и могут быть изменены после создания с помощью нескольких методов, таких какadd(). - Множества-константы
-
Они представляют собой неизменяемое множество. Они создаются с помощью встроенного конструктора
frozenset(). Поскольку множество-константа неизменяемо и хешируемо, его можно использовать в качестве элемента другого множества или как ключ словаря.
- Отображения
-
Они представляют собой конечные наборы объектов, индексированные произвольными наборами индексов. Нотация подстрочных индексов
a[k]выбирает элемент, индексированный значениемkиз отображенияa; это может использоваться в выражениях и в качестве цели для присваивания или операторовdel. Встроенная функцияlen()возвращает количество элементов в отображении.В настоящее время существует единственный встроенный тип отображения:
- Словари
-
Они представляют собой конечные наборы объектов, индексированных почти произвольными значениями. Единственными типами значений, неприемлемыми в качестве ключей, являются значения, содержащие списки или словари или другие изменяемые типы, сравниваемые по значению, а не по идентификатору объекта. Причина в том, что для эффективной реализации словарей значение хэш-функции ключа должно оставаться постоянным. Для числовых типов, используемых в качестве ключей, применяются стандартные правила сравнения чисел: если два числа равны (например,
1и1.0), то их можно использовать взаимозаменяемо для индексации одной и той же записи словаря.Словари сохраняют порядок вставки, что означает, что ключи будут генерироваться в том же порядке, в котором они были добавлены последовательно в словарь. Замена существующего ключа не изменяет порядок, однако удаление ключа и повторная вставка добавят его в конец, вместо сохранения его старого места.
Словари изменяемы; они могут быть созданы с помощью обозначения
{...}(см. раздел Отображения словарей).Модули расширения
dbm.ndbmиdbm.gnuпредоставляют дополнительные примеры типов отображения, а также модульcollections.Изменено в версии 3.7: Словари не сохраняли порядок вставки в версиях Python до 3.6. В CPython 3.6 порядок вставки сохранялся, но в то время он считался деталью реализации, а не гарантией языка.
- Вызываемые типы
-
Вот типы, к которым можно применить операцию вызова функции (см. раздел Вызовы):
- Определённые пользователем функции
-
Объект пользовательской функции создаётся с помощью определения функции (см. раздел Определения функций). Его следует вызывать со списком аргументов, содержащим такое же количество элементов, что и список формальных параметров функции.
Специальные атрибуты:
Атрибут
Значение
__doc__Строка документации функции, или
Noneесли она недоступна; не наследуется подклассами.Изменяемый
Имя функции.
Изменяемый
Полное имя функции.
Введено в версии 3.3.
Изменяемый
__module__Имя модуля, в котором была определена функция, или
Noneесли оно недоступно.Изменяемый
__defaults__Кортеж, содержащий значения аргументов по умолчанию для аргументов, у которых они заданы, или
Noneесли у аргументов нет значений по умолчанию.Изменяемый
__code__Объект кода, представляющий тело скомпилированной функции.
Изменяемый
__globals__Ссылка на словарь, содержащий глобальные переменные функции — глобальное пространство имён модуля, в котором была определена функция.
Только для чтения
Пространство имён, поддерживающее произвольные атрибуты функции.
Изменяемый
__closure__Noneили кортеж ячеек, содержащих привязки к свободным переменным функции. См. информацию об атрибутеcell_contentsниже.Только для чтения
__annotations__Словарь, содержащий аннотации параметров. Ключи словаря — имена параметров, и
'return'для аннотации возвращаемого значения, если она задана.Изменяемый
__kwdefaults__Словарь, содержащий значения по умолчанию для параметров только для ключевых слов.
Изменяемый
Большинство атрибутов, помеченных как «Изменяемый», проверяют тип присваиваемого значения.
Объекты функций также поддерживают получение и установку произвольных атрибутов, которые могут использоваться, например, для прикрепления метаданных к функциям. Для получения и установки таких атрибутов используется обычная запись с точкой. Обратите внимание, что текущая реализация поддерживает атрибуты функций только для определённых пользователем функций. Атрибуты функций встроенных функций могут быть добавлены в будущем.
Объект ячейки имеет атрибут
cell_contents. Его можно использовать для получения значения ячейки, а также для установки значения.Дополнительную информацию об определении функции можно получить из её объекта кода; см. описание внутренних типов ниже. Тип
cellдоступен в модулеtypes. - Методы экземпляра
-
Объект метода экземпляра объединяет класс, экземпляр класса и любой вызываемый объект (обычно определённую пользователем функцию).
Специальные атрибуты только для чтения:
__self__— объект экземпляра класса,__func__— объект функции;__doc__— документация метода (такая же как__func__.__doc__);__name__— имя метода (такое же как__func__.__name__);__module__— имя модуля, в котором был определён метод, илиNoneесли оно недоступно.Методы также поддерживают доступ (но не настройку) произвольных атрибутов функций на базовом объекте функции.
Определённые пользователем объекты методов могут быть созданы при получении атрибута класса (возможно, через экземпляр этого класса), если этот атрибут является объектом определённой пользователем функции или объектом метода класса.
Когда объект метода экземпляра создаётся путём получения объекта определённой пользователем функции из класса через один из его экземпляров, атрибут
__self__объекта — это экземпляр, и метод называется связанным. Атрибут__func__нового метода — это исходный объект функции.Когда объект метода экземпляра создаётся путём получения объекта метода класса из класса или экземпляра, атрибут
__self__объекта — сам класс, а атрибут__func__объекта — объект функции, лежащий в основе метода класса.Когда вызывается объект метода экземпляра, базовая функция (
__func__) вызывается, вставляя экземпляр класса (__self__) в начало списка аргументов. Например, когдаC— класс, содержащий определение функцииf(), иx— экземплярC, вызовx.f(1)эквивалентен вызовуC.f(x, 1).Когда объект метода экземпляра получен из объекта метода класса, «экземпляр класса», хранящийся в
__self__, на самом деле будет сам классом, поэтому вызовx.f(1)илиC.f(1)эквивалентен вызовуf(C,1), гдеf— базовая функция.Обратите внимание, что преобразование из объекта функции в объект метода экземпляра происходит каждый раз, когда атрибут извлекается из экземпляра. В некоторых случаях полезной оптимизацией является присвоение атрибута локальной переменной и вызов этой локальной переменной. Также обратите внимание, что это преобразование происходит только для определённых пользователем функций; другие вызываемые объекты (и все невызываемые объекты) извлекаются без преобразования. Также важно отметить, что определённые пользователем функции, которые являются атрибутами экземпляра класса, не преобразуются в связанные методы; это происходит *только* тогда, когда функция является атрибутом класса.
- Генераторные функции
-
Функция или метод, использующий оператор
yield(см. раздел Оператор yield), называется генераторной функцией. Такая функция, когда вызывается, всегда возвращает объект итератора, который можно использовать для выполнения тела функции: вызов методаiterator.__next__()итератора заставит функцию выполняться до тех пор, пока она не предоставит значение с помощью оператораyield. Когда функция выполняет операторreturnили завершается, возникает исключениеStopIteration, и итератор достигнет конца набора возвращаемых значений. - Функции-генераторы
-
Функция или метод, определённые с помощью
async def, называются функциями-генераторами. Такая функция, когда вызывается, возвращает объект генератора. В ней могут содержаться выраженияawait, а также операторыasync withиasync for. См. также раздел Объекты-генераторы. - Асинхронные генераторные функции
-
Функция или метод, определённые с помощью
async defи использующие операторyield, называются асинхронными генераторными функциями. Такая функция, когда вызывается, возвращает объект асинхронного итератора, который можно использовать в оператореasync forдля выполнения тела функции.Вызов метода
aiterator.__anext__()асинхронного итератора вернёт awaitable, которое при ожидании выполнит выполнение, пока не предоставит значение с помощью выраженияyield. Когда функция выполняет пустой операторreturnили завершается, возникает исключениеStopAsyncIteration, и асинхронный итератор достигнет конца набора значений для возврата. - Встроенные функции
-
Встроенный объект функции является оболочкой вокруг функции C. Примеры встроенных функций —
len()иmath.sin()(math— стандартный встроенный модуль). Количество и тип аргументов определяются функцией C. Специальные атрибуты только для чтения:__doc__— строка документации функции илиNone, если она недоступна;__name__— имя функции;__self__установлено в значениеNone(но см. следующий пункт);__module__— имя модуля, в котором определена функция, илиNone, если оно недоступно. - Встроенные методы
-
Это фактически другое воплощение встроенной функции, на этот раз содержащей объект, переданный функции C в качестве неявного дополнительного аргумента. Пример встроенного метода —
alist.append(), предполагая, что alist — объект списка. В этом случае специальный атрибут только для чтения__self__установлен в значение объекта, обозначенного alist. - Классы
-
Классы вызываемы. Эти объекты обычно действуют как фабрики для создания новых экземпляров самих себя, но возможны вариации для типов классов, которые переопределяют
__new__(). Аргументы вызова передаются в__new__()и, в типичном случае, в__init__()для инициализации нового экземпляра. - Экземпляры классов
-
Экземпляры произвольных классов могут быть сделаны вызываемыми путем определения метода
__call__()в их классе.
-
- Модули
-
Модули — базовая единица организации кода Python, создаваемая системой импорта (система импорта), вызываемой либо с помощью инструкции
import, либо вызывая функции, такие какimportlib.import_module(), и встроенную функцию__import__(). Объект модуля имеет пространство имен, реализованное объектом словаря (это словарь, на который ссылается атрибут__globals__функций, определенных в модуле). Ссылки на атрибуты переводятся в поиск в этом словаре, например,m.xэквивалентноm.__dict__["x"]. Объект модуля не содержит объект кода, используемый для инициализации модуля (поскольку он не нужен после завершения инициализации).Присвоение атрибута обновляет словарь пространства имен модуля, например,
m.x = 1эквивалентноm.__dict__["x"] = 1.Предопределенные (изменяемые) атрибуты:
__name__— имя модуля;__doc__— строка документации модуля илиNone, если она недоступна;__annotations__(необязательно) — словарь, содержащий аннотации переменных, собранные во время выполнения тела модуля;__file__— путь к файлу, из которого был загружен модуль, если он был загружен из файла. Атрибут__file__может отсутствовать для определенных типов модулей, например, для C-модулей, статически связанных с интерпретатором; для расширенных модулей, загруженных динамически из общей библиотеки, это путь к файлу общей библиотеки.Специальный атрибут только для чтения:
__dict__— пространство имен модуля как объект словаря.Деталь реализации CPython: Из-за способа очистки словарей модулей в CPython словарь модуля очищается, когда модуль выходит из области видимости, даже если словарь все еще имеет активные ссылки. Чтобы избежать этого, скопируйте словарь или сохраните модуль, пока напрямую используете его словарь.
- Пользовательские классы
-
Типы пользовательских классов обычно создаются с помощью определений классов (см. раздел Определения классов). Класс имеет пространство имен, реализованное объектом словаря. Ссылки на атрибуты класса переводятся в поиск в этом словаре, например,
C.xпереводится вC.__dict__["x"](хотя существует ряд хуков, которые позволяют использовать и другие способы определения атрибутов). Если имя атрибута не найдено, поиск атрибута продолжается в базовых классах. Этот поиск базовых классов использует порядок разрешения методов C3, который ведет себя правильно даже при наличии структуры наследования «ромб», где существует несколько путей наследования обратно к общему предку. Дополнительные сведения об используемом C3 MRO Python можно найти в документации, сопровождающей выпуск 2.3 по адресу https://www.python.org/download/releases/2.3/mro/.Когда ссылка на атрибут класса (например, для класса
C) приведет к объекту метода класса, он преобразуется в объект метода экземпляра, чьим атрибутом__self__являетсяC. Когда он приводит к объекту статического метода, он преобразуется в объект, заключенный в объекте статического метода. См. раздел Реализация описателей для другого способа, которым атрибуты, полученные из класса, могут отличаться от тех, которые фактически содержатся в его__dict__.Присвоение атрибута класса обновляет словарь класса, но никогда словарь базового класса.
Объект класса может быть вызван (см. выше), чтобы получить экземпляр класса (см. ниже).
Специальные атрибуты:
__name__— имя класса;__module__— имя модуля, в котором был определен класс;__dict__— словарь, содержащий пространство имен класса;__bases__— кортеж, содержащий базовые классы в порядке их появления в списке базовых классов;__doc__— строка документации класса илиNone, если она не определена;__annotations__(необязательно) — словарь, содержащий аннотации переменных, собранные во время выполнения тела класса. - Экземпляры классов
-
Экземпляр класса создается путем вызова объекта класса (см. выше). Экземпляр класса имеет пространство имен, реализованное как словарь, который является первой точкой поиска ссылок на атрибуты. Если атрибут не найден там и у класса экземпляра есть атрибут с таким именем, поиск продолжается с атрибутами класса. Если найденный атрибут класса — это пользовательская функция, она преобразуется в объект метода экземпляра, чьим атрибутом
__self__является экземпляр. Объекты статических и методов класса также преобразуются; см. выше раздел «Классы». См. раздел Реализация описателей для другого способа, которым атрибуты класса, полученные через экземпляры, могут отличаться от объектов, фактически хранящихся в__dict__класса. Если атрибут класса не найден и у класса объекта есть метод__getattr__(), этот метод вызывается для удовлетворения поиска.Присвоения и удаления атрибутов обновляют словарь экземпляра, но никогда словарь класса. Если у класса есть метод
__setattr__()или__delattr__(), он вызывается вместо прямого обновления словаря экземпляра.Экземпляры классов могут имитировать числа, последовательности или отображения, если они имеют методы с определенными специальными именами. См. раздел Специальные имена методов.
Специальные атрибуты:
__dict__— словарь атрибутов;__class__— класс экземпляра. - Объекты ввода-вывода (также известные как объекты файлов)
-
Объект файлового объекта представляет собой открытый файл. Доступны различные сокращения для создания объектов файлов: встроенная функция
open(), а такжеos.popen(),os.fdopen()и методmakefile()объектов сокета (и, возможно, другие функции или методы, предоставляемые модулями расширения).Объекты
sys.stdin,sys.stdoutиsys.stderrинициализируются файловыми объектами, соответствующими стандартным потокам ввода, вывода и ошибок интерпретатора; все они открыты в текстовом режиме и, следовательно, следуют интерфейсу, определённому абстрактным классомio.TextIOBase. - Внутренние типы
-
Некоторые типы, используемые интерпретатором внутри, доступны пользователю. Их определения могут меняться в будущих версиях интерпретатора, но они упомянуты здесь для полноты.
- Объекты кода
-
Объекты кода представляют собой скомпилированный в байт-код исполняемый Python-код, или байт-код. Разница между объектом кода и объектом функции состоит в том, что объект функции содержит явную ссылку на глобальные переменные функции (модуль, в котором она была определена), а объект кода — нет; также значения аргументов по умолчанию хранятся в объекте функции, а не в объекте кода (поскольку они представляют значения, вычисляемые во время выполнения). В отличие от объектов функций, объекты кода неизменяемы и не содержат ссылок (прямых или косвенных) на изменяемые объекты.
Специальные атрибуты только для чтения:
co_name— имя функции;co_argcount— общее количество позиционных аргументов (включая позиционные-только аргументы и аргументы с значениями по умолчанию);co_posonlyargcount— количество позиционных-только аргументов (включая аргументы с значениями по умолчанию);co_kwonlyargcount— количество аргументов только по ключевым словам (включая аргументы с значениями по умолчанию);co_nlocals— количество локальных переменных, используемых функцией (включая аргументы);co_varnames— кортеж, содержащий имена локальных переменных (начиная с имен аргументов);co_cellvars— кортеж, содержащий имена локальных переменных, на которые ссылаются вложенные функции;co_freevars— кортеж, содержащий имена свободных переменных;co_code— строка, представляющая последовательность инструкций байт-кода;co_consts— кортеж, содержащий литералы, используемые байт-кодом;co_names— кортеж, содержащий имена, используемые байт-кодом;co_filename— имя файла, из которого был скомпилирован код;co_firstlineno— номер первой строки функции;co_lnotab— строка, кодирующая отображение смещений байт-кода на номера строк (подробнее см. исходный код интерпретатора);co_stacksize— требуемый размер стека;co_flags— целое число, кодирующее количество флагов для интерпретатора.Для
co_flagsопределены следующие биты флагов: бит0x04установлен, если функция использует синтаксис*arguments, чтобы принять произвольное количество позиционных аргументов; бит0x08установлен, если функция использует синтаксис**keywords, чтобы принять произвольное количество аргументов по ключевым словам; бит0x20установлен, если функция является генератором.Декларации будущих функций (
from __future__ import division) также используют биты вco_flags, чтобы указать, был ли объект кода скомпилирован с включённой определённой функцией: бит0x2000установлен, если функция была скомпилирована с включённой будущей функцией деления; биты0x10и0x1000использовались в более ранних версиях Python.Другие биты в
co_flagsзарезервированы для внутреннего использования.Если объект кода представляет функцию, первым элементом в
co_constsявляется строка документации функции, илиNone, если она не определена.
- Объекты фреймов
-
Объекты фреймов представляют собой фреймы выполнения. Они могут встречаться в объектах отслеживания ошибок (см. ниже), а также передаются в зарегистрированные функции отслеживания.
Специальные атрибуты только для чтения:
f_back— предыдущий фрейм стека (в сторону вызывающей функции), илиNone, если это нижний фрейм стека;f_code— объект кода, выполняемый в этом фрейме;f_locals— словарь, используемый для поиска локальных переменных;f_globalsиспользуется для глобальных переменных;f_builtinsиспользуется для встроенных (внутренних) имён;f_lastiуказывает точную инструкцию (это индекс в строке байт-кода объекта кода).Обращение к
f_codeвызывает событие отслеживания отслеживанияobject.__getattr__с аргументамиobjи"f_code".Специальные атрибуты для записи:
f_trace, если неNone, — функция, вызываемая для различных событий во время выполнения кода (это используется отладчиком). Обычно событие вызывается для каждой новой строки исходного кода — это можно отключить, установивf_trace_linesвFalse.Реализации могут позволять запрашивать события по каждой инструкции, устанавливая
f_trace_opcodesвTrue. Обратите внимание, что это может привести к неопределённому поведению интерпретатора, если исключения, поднятые функцией отслеживания, выходят за пределы отслеживаемой функции.f_lineno— текущий номер строки фрейма — запись в этот атрибут внутри функции отслеживания переходит к заданной строке (только для самого нижнего фрейма). Отладчик может реализовать команду Переход (иначе известную как Установка следующей инструкции) записью в f_lineno.Объекты фреймов поддерживают один метод:
-
frame.clear() -
Этот метод очищает все ссылки на локальные переменные, хранящиеся в фрейме. Также, если фрейм принадлежал генератору, генератор завершается. Это помогает разорвать циклы ссылок, включающие объекты фреймов (например, при перехвате исключения и сохранении его трассировки для последующего использования).
RuntimeErrorвозникает, если фрейм выполняется в данный момент.Добавлена в версии 3.4.
-
- Объекты трассировки
-
Объекты трассировки представляют собой трассировку стека исключения. Объект трассировки неявно создаётся при возникновении исключения, а также может быть явно создан путём вызова
types.TracebackType.Для неявно созданных трассировок, когда поиск обработчика исключения разворачивает стек выполнения, на каждом уровне развёртывания в стек вставляется объект трассировки перед текущей трассировкой. При входе в обработчик исключения трассировка стека становится доступной программе. (См. раздел Оператор try.) Она доступна как третий элемент кортежа, возвращаемого
sys.exc_info(), и как атрибут__traceback__перехваченного исключения.Когда в программе нет подходящего обработчика, трассировка стека записывается (в красивом формате) в стандартный поток ошибок; если интерпретатор интерактивный, он также становится доступным пользователю как
sys.last_traceback.Для явно созданных трассировок, создатель трассировки должен определить, как атрибуты
tb_nextдолжны быть связаны для формирования полной трассировки стека.Специальные атрибуты только для чтения:
tb_frameуказывает на фрейм выполнения текущего уровня;tb_linenoсодержит номер строки, где возникло исключение;tb_lastiуказывает на точную инструкцию. Номер строки и последняя инструкция в трассировке могут отличаться от номера строки объекта фрейма, если исключение произошло в оператореtryбез соответствующего оператора except или с оператором finally.Обращение к
tb_frameвызывает событие отслеживания отслеживанияobject.__getattr__с аргументамиobjи"tb_frame".Специальный атрибут для записи:
tb_next— следующий уровень в трассировке стека (в сторону фрейма, где возникло исключение), илиNone, если следующего уровня нет.Изменено в версии 3.7: Теперь объекты трассировки могут быть явно созданы из кода Python, и атрибут
tb_nextсуществующих экземпляров может быть обновлён. - Объекты срезов
-
Объекты срезов используются для представления срезов для методов
__getitem__(). Они также создаются встроенной функциейslice().Специальные атрибуты только для чтения:
start— нижняя граница;stop— верхняя граница;step— значение шага; каждое из нихNone, если опущено. Эти атрибуты могут иметь любой тип.Объекты срезов поддерживают один метод:
-
slice.indices(self, length) -
Этот метод принимает единственный целочисленный аргумент length и вычисляет информацию о срезе, который объект среза описывает, если он применяется к последовательности из length элементов. Он возвращает кортеж из трёх целых чисел; соответственно, это начальный и конечный индексы и шаг или длина шага среза. Отсутствующие или вне диапазона индексы обрабатываются согласованно с обычными срезами.
-
- Объекты статических методов
-
Объекты статических методов предоставляют способ предотвращения преобразования объектов функций в объекты методов, описанного выше. Объект статического метода является обёрткой вокруг любого другого объекта, обычно объекта пользовательского метода. Когда объект статического метода извлекается из класса или экземпляра класса, фактически возвращаемым объектом является обернутый объект, который не подвергается дальнейшему преобразованию. Объекты статических методов сами по себе не вызываемы, хотя объекты, которые они оборачивают, обычно вызываемы. Объекты статических методов создаются встроенным конструктором
staticmethod(). - Объекты методов класса
-
Объект метода класса, подобно объекту статического метода, является обёрткой вокруг другого объекта, который изменяет способ получения этого объекта из классов и экземпляров классов. Поведение объектов методов класса при таком извлечении описано выше, в разделе «Пользовательские методы». Объекты методов класса создаются встроенным конструктором
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__()настраивает его), ни одно не-Noneзначение не может быть возвращено методом__init__(); в противном случае будет вызвано исключениеTypeError.
-
object.__del__(self) -
Вызывается, когда экземпляр собирается быть уничтожен. Это также называется финализатором или (неправильно) деструктором. Если у базового класса есть метод
__del__(), метод__del__()производного класса, если таковой имеется, должен явно его вызвать, чтобы гарантировать правильное удаление части базового класса экземпляра.Возможна (хотя и не рекомендуется!) ситуация, когда метод
__del__()откладывает уничтожение экземпляра, создавая новую ссылку на него. Это называется воскрешением объекта. Зависит от реализации, будет ли__del__()вызван второй раз, когда воскрешённый объект собирается быть уничтожен; в текущей реализации CPython он вызывается только один раз.Не гарантируется, что методы
__del__()вызываются для объектов, которые всё ещё существуют при выходе интерпретатора.Примечание
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.__str__(self) -
Вызывается функцией
str(object)и встроенными функциямиformat()иprint()для вычисления «неформального» или красиво отображаемого строкового представления объекта. Возвращаемое значение должно быть объектом типа строка.Этот метод отличается от
object.__repr__()тем, что нет ожидания, что__str__()вернёт допустимое выражение Python: может использоваться более удобное или краткое представление.Реализация по умолчанию, определенная встроенным типом
object, вызываетobject.__repr__().
-
object.__format__(self, format_spec) -
Вызывается функцией
format()из стандартной библиотеки, а также при вычислении форматированных строковых литералов и методаstr.format()для создания «отформатированного» строкового представления объекта. Аргумент format_spec — это строка, содержащая описание желаемых параметров форматирования. Интерпретация аргумента format_spec зависит от типа, реализующего метод__format__(), однако большинство классов либо делегируют форматирование одному из встроенных типов, либо используют похожую синтаксическую структуру для опций форматирования.См. Мини-язык спецификаций форматирования для описания стандартного синтаксиса форматирования.
Возвращаемое значение должно быть строковым объектом.
Изменено в версии 3.4: Метод __format__ класса
objectсам вызываетTypeError, если ему передана любая непустая строка.Изменено в версии 3.7:
object.__format__(x, '')теперь эквивалентенstr(x), а неformat(str(self), '').
-
object.__lt__(self, other) -
object.__le__(self, other) -
object.__eq__(self, other) -
object.__ne__(self, other) -
object.__gt__(self, other) -
object.__ge__(self, other) -
Это так называемые методы «богатого сравнения». Соответствие между символами операторов и именами методов следующее:
x<yвызываетx.__lt__(y),x<=yвызываетx.__le__(y),x==yвызываетx.__eq__(y),x!=yвызываетx.__ne__(y),x>yвызываетx.__gt__(y), иx>=yвызываетx.__ge__(y).Метод богатого сравнения может вернуть объект-синглтон
NotImplemented, если он не реализует операцию для заданной пары аргументов. По соглашению, для успешного сравнения возвращаютсяFalseиTrue. Однако эти методы могут возвращать любое значение, поэтому, если оператор сравнения используется в контексте булевых значений (например, в условии оператораif), Python вызоветbool()для определения, является ли результат истинным или ложным.По умолчанию,
objectреализует__eq__()с помощьюis, возвращаяNotImplementedв случае ложного сравнения:True if x is y else NotImplemented. Для__ne__()по умолчанию делегируется__eq__()и инвертируется результат, если он неNotImplemented. Других предполагаемых взаимосвязей между операторами сравнения или реализациями по умолчанию нет; например, истинность(x<y or x==y)не подразумеваетx<=y. Чтобы автоматически генерировать операции упорядочения из одной исходной операции, см.functools.total_ordering().См. абзац о методе
__hash__()для важных замечаний по созданию хешируемых объектов, которые поддерживают пользовательские операции сравнения и могут использоваться в качестве ключей словарей.Нет методов с переставленными аргументами (которые нужно использовать, когда левый аргумент не поддерживает операцию, но правый поддерживает); скорее,
__lt__()и__gt__()являются отражениями друг друга,__le__()и__ge__()являются отражениями друг друга, а__eq__()и__ne__()являются собственными отражениями. Если операнды имеют разные типы, и тип правого операнда является прямым или косвенным подклассом типа левого операнда, приоритет имеет отраженный метод правого операнда, в противном случае приоритет имеет метод левого операнда. Виртуальное наследование не учитывается.
-
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__(); с ними все объекты считаются неравными (кроме себя) иx.__hash__()возвращает соответствующее значение, такое чтоx is yиhash(x) == hash(y).Класс, переопределяющий
__eq__()и не определяющий__hash__(), будет иметь__hash__()неявным образом установленным вNone. Когда метод__hash__()классаNone, экземпляры класса будут вызывать соответствующую ошибкуTypeErrorпри попытке получить их значение хэша и также будут корректно идентифицированы как нехешируемые при проверкеisinstance(obj, collections.abc.Hashable).Если класс, переопределяющий
__eq__(), должен сохранить реализацию__hash__()от родительского класса, интерпретатор должен быть явно проинформирован об этом, установив__hash__ = <ParentClass>.__hash__.Если класс, не переопределяющий
__eq__(), хочет подавить поддержку хэша, он должен включать__hash__ = Noneв определении класса. Класс, который определяет свой собственный__hash__(), который явно вызываетTypeError, будет неправильно идентифицирован как хешируемый вызовомisinstance(obj, collections.abc.Hashable).Примечание
По умолчанию значения хэша
__hash__()для объектов str и bytes «солят» с помощью случайного значения, непредсказуемого для каждого запуска программы. Хотя они остаются постоянными в одном процессе Python, они непредсказуемы при повторных запусках Python.Это призвано обеспечить защиту от отказа в обслуживании, вызванного специально подобранными входными данными, которые эксплуатируют худший случай производительности вставки в словарь, сложность O(n^2). Подробности см. в http://www.ocert.org/advisories/ocert-2011-003.html.
Изменение значений хэшей влияет на порядок итерации множеств. Python никогда не гарантировал этот порядок (и он обычно отличается в 32-битных и 64-битных сборках).
См. также
PYTHONHASHSEED.Изменено в версии 3.3: Рандомизация хэшей включена по умолчанию.
-
object.__bool__(self) -
Вызывается для проверки истинности и встроенной операции
bool(); должно возвращатьFalseилиTrue. Если этот метод не определен, вызывается__len__(), если он определен, и объект считается истинным, если его результат отличен от нуля. Если класс не определяет ни__len__(), ни__bool__(), все его экземпляры считаются истинными.
3.3.2. Настройка доступа к атрибутам
Следующие методы можно определить для настройки поведения доступа к атрибутам (использования, присваивания или удаления x.name) экземпляров класса.
-
object.__getattr__(self, name) -
Вызывается, когда стандартный доступ к атрибуту завершается ошибкой
AttributeError(либо__getattribute__()вызываетAttributeError, так как имя не является атрибутом экземпляра или атрибутом в дереве класса дляself; или__get__()свойства имя вызываетAttributeError). Этот метод должен вернуть значение атрибута (вычисленное) или вызвать исключениеAttributeError.Обратите внимание, что если атрибут найден обычным механизмом,
__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.__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 класса-владельца.
-
object.__set_name__(self, owner, name) -
Вызывается в момент создания владеющего класса owner. Дескриптор был назначен в name.
Примечание
__set_name__()вызывается только неявно как часть конструктораtype, поэтому его необходимо вызвать явно с соответствующими параметрами, когда дескриптор добавляется в класс после его первоначального создания:class A: pass descr = custom_descriptor() A.attr = descr descr.__set_name__(A, 'attr')
Дополнительную информацию см. в разделе Создание объекта класса.
В версии 3.6.
Атрибут __objclass__ интерпретируется модулем inspect как указывающий на класс, где был определен этот объект (установка этого значения корректно может помочь при интроспекции динамических атрибутов класса во время выполнения). Для вызываемых объектов это может указывать на то, что экземпляр данного типа (или подкласса) ожидается или требуется в качестве первого позиционного аргумента (например, CPython устанавливает этот атрибут для несвязанных методов, реализованных на C).
3.3.2.3. Вызов дескрипторов
В общем случае дескриптор — это атрибут объекта с «поведением связывания», чья обработка доступа к атрибутам была переопределена методами протокола дескрипторов: __get__(), __set__() и __delete__(). Если любой из этих методов определен для объекта, то он называется дескриптором.
По умолчанию доступ к атрибуту заключается в получении, установке или удалении атрибута из словаря объекта. Например, a.x имеет цепочку поиска, начинающуюся с a.__dict__['x'], затем type(a).__dict__['x'], и продолжающуюся через базовые классы type(a), исключая метаклассы.
Однако, если полученное значение является объектом, определяющим один из методов дескрипторов, Python может переопределить поведение по умолчанию и вызвать метод дескриптора вместо него. Место, где это происходит в цепочке приоритета, зависит от того, какие методы дескрипторов были определены и как они были вызваны.
Точка входа для вызова дескриптора — это связывание, a.x. Способ сборки аргументов зависит от a:
- Прямой вызов
-
Самый простой и наименее распространенный вызов — когда пользовательский код напрямую вызывает метод дескриптора:
x.__get__(a). - Связывание с экземпляром
-
Если связывание происходит с экземпляром объекта,
a.xпреобразуется в вызов:type(a).__dict__['x'].__get__(a, type(a)). - Связывание с классом
-
Если связывание происходит с классом,
A.xпреобразуется в вызов:A.__dict__['x'].__get__(None, A). - Связывание с super
-
Если
aявляется экземпляромsuper, то связываниеsuper(B, obj).m()ищет вobj.__class__.__mro__базовый классAнепосредственно предшествующийBи затем вызывает дескриптор с вызовом:A.__dict__['m'].__get__(obj, obj.__class__).
Для связываний с экземплярами порядок вызова дескрипторов зависит от определенных методов дескрипторов. Дескриптор может определять любую комбинацию __get__(), __set__() и __delete__(). Если он не определяет __get__(), то доступ к атрибуту вернет сам объект дескриптора, если только в словаре экземпляра объекта нет значения. Если дескриптор определяет __set__() и/или __delete__(), он является дескриптором данных; если ни того, ни другого не определено, то это дескриптор не данных. Обычно дескрипторы данных определяют как __get__(), так и __set__(), а дескрипторы не данных — только __get__() метод. Дескрипторы данных с определенными __set__() и __get__() всегда переопределяют переопределение в словаре экземпляра. В противоположность этому, дескрипторы не данных могут быть переопределены экземплярами.
Методы Python (включая staticmethod() и classmethod()) реализуются как дескрипторы не данных. Соответственно, экземпляры могут переопределять и изменять поведение методов. Это позволяет отдельным экземплярам приобретать поведение, отличное от других экземпляров того же класса.
Функция property() реализуется как дескриптор данных. Соответственно, экземпляры не могут переопределить поведение свойства.
3.3.2.4. __slots__
__slots__ позволяют явно объявлять данные члены (например, свойства) и запрещать создание __dict__ и __weakref__ (если они не объявлены явно в __slots__ или доступны в родительском классе).
Экономия памяти по сравнению с использованием __dict__ может быть существенной. Скорость поиска атрибутов также может быть значительно улучшена.
-
object.__slots__ -
Эта переменная класса может быть присвоена строкой, итерируемым объектом или последовательностью строк с именами переменных, используемых экземплярами. __slots__ резервирует место для объявленных переменных и предотвращает автоматическое создание __dict__ и __weakref__ для каждого экземпляра.
3.3.2.4.1. Примечания по использованию __slots__
- При наследовании от класса без __slots__ атрибуты __dict__ и __weakref__ экземпляров всегда будут доступны.
- Без переменной __dict__ экземплярам нельзя назначать новые переменные, не указанные в определении __slots__. Попытка присвоить имя переменной, не указанной в __slots__, вызывает исключение
AttributeError. Если требуется динамическое назначение новых переменных, добавьте'__dict__'в последовательность строк в объявлении __slots__. - Без переменной __weakref__ для каждого экземпляра классы, определяющие __slots__, не поддерживают слабые ссылки на свои экземпляры. Если поддержка слабых ссылок необходима, добавьте
'__weakref__'в последовательность строк в объявлении __slots__. - __slots__ реализуются на уровне класса путем создания описателей (Реализация описателей) для каждого имени переменной. В результате, атрибуты класса не могут быть использованы для установки значений по умолчанию для переменных экземпляров, определенных с помощью __slots__; в противном случае, атрибут класса перезапишет назначение описателя.
- Действие объявления __slots__ не ограничено классом, в котором оно определено. __slots__, объявленные в родительских классах, доступны в дочерних классах. Однако дочерние подклассы получат __dict__ и __weakref__, если они также не определят __slots__ (который должен содержать только имена любых дополнительных слотов).
- Если класс определяет слот, также определенный в базовом классе, переменная экземпляра, определенная слотом базового класса, недоступна (кроме как путем прямого получения её описателя из базового класса). Это делает смысл программы неопределенным. В будущем может быть добавлена проверка, чтобы предотвратить это.
- Непустые __slots__ не работают для классов, производных от «переменных» встроенных типов, таких как
int,bytesиtuple. - Любой итерируемый объект, не являющийся строкой, может быть присвоен __slots__. Также могут использоваться отображения; однако в будущем значениям, соответствующим каждому ключу, может быть присвоено специальное значение.
- Присвоение __class__ работает только если оба класса имеют одинаковые __slots__.
- Множественное наследование с несколькими родительскими классами с __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.
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
Если базовый элемент, который появляется в определении класса, не является экземпляром type, то ищется метод __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__, после создания объекта класса вызываются следующие дополнительные шаги настройки:
- во-первых,
type.__new__собирает все дескрипторы в пространстве имён класса, которые определяют метод__set_name__(); - во-вторых, все эти методы
__set_name__вызываются с определением класса и присвоенным именем данного дескриптора; - наконец, хук
__init_subclass__()вызывается для непосредственного родителя нового класса в его порядке разрешения методов.
После создания объекта класса он передаётся декораторам классов, включённым в определение класса (если таковые имеются), и полученный объект привязывается в локальном пространстве имён как определённый класс.
При создании нового класса с помощью type.__new__, объект, предоставленный в качестве параметра пространства имён, копируется в новую упорядоченную карту, а исходный объект отбрасывается. Новая копия оборачивается в прокси только для чтения, которая становится атрибутом __dict__ объекта класса.
См. также
- PEP 3135 — Новый super
-
Описывает неявную
__class__ссылку на замыкание
3.3.3.7. Применение метаклассов
Потенциальные применения метаклассов безграничны. Некоторые идеи, которые были исследованы, включают перечисления, ведение журналов, проверку интерфейсов, автоматическую делегацию, автоматическое создание свойств, прокси, фреймворки и автоматическое блокирование/синхронизацию ресурсов.
3.3.4. Настройка проверок экземпляра и подкласса
Следующие методы используются для переопределения стандартного поведения встроенных функций isinstance() и issubclass().
В частности, метакласс abc.ABCMeta реализует эти методы, чтобы разрешить добавление абстрактных базовых классов (ABC) в качестве «виртуальных базовых классов» к любому классу или типу (включая встроенные типы), включая другие ABC.
-
class.__instancecheck__(self, instance) -
Возвращает true, если instance должен считаться экземпляром (прямым или косвенным) class. Если определён, вызывается для реализации
isinstance(instance, class).
-
class.__subclasscheck__(self, subclass) -
Возвращает true, если subclass должен считаться подклассом (прямым или косвенным) class. Если определён, вызывается для реализации
issubclass(subclass, class).
Обратите внимание, что эти методы ищутся в типе (метаклассе) класса. Они не могут быть определены как методы класса в самом классе. Это согласуется с поиском специальных методов, которые вызываются на экземплярах, только в этом случае экземпляр сам является классом.
См. также
- PEP 3119 - Введение абстрактных базовых классов
-
Включает спецификацию для настройки поведения
isinstance()иissubclass()через__instancecheck__()и__subclasscheck__(), с мотивацией этой функциональности в контексте добавления абстрактных базовых классов (см. модульabc) в язык.
3.3.5. Эмуляция обобщённых типов
Можно реализовать синтаксис обобщённых классов, как указано в PEP 484 (например, List[int]) путём определения специального метода:
-
classmethod object.__class_getitem__(cls, key) -
Возвращает объект, представляющий специализацию обобщённого класса аргументами типов, найденными в key.
Этот метод ищется в самом объекте класса, и когда он определён в теле класса, этот метод неявно является методом класса. Обратите внимание, что этот механизм в первую очередь предназначен для использования со статическими подсказками типов, другие варианты использования не рекомендуются.
См. также
PEP 560 - Основная поддержка модуля typing и обобщённых типов
3.3.6. Эмуляция вызываемых объектов
-
object.__call__(self[, args...]) -
Вызывается, когда экземпляр вызывается как функция; если этот метод определён,
x(arg1, arg2, ...)примерно эквивалентноtype(x).__call__(x, arg1, ...).
3.3.7. Эмуляция типов контейнеров
Следующие методы могут быть определены для реализации объектов-контейнеров. Контейнеры обычно представляют собой последовательности (такие как списки или кортежи) или отображения (например, словари), но также могут представлять и другие контейнеры. Первый набор методов используется для эмуляции последовательности или отображения; разница заключается в том, что для последовательности допустимыми ключами должны быть целые числа k, для которых 0 <= k <
N, где N — длина последовательности, или объекты срезов, определяющие диапазон элементов. Также рекомендуется, чтобы отображения предоставляли методы keys(), values(), items(), get(), clear(), setdefault(), pop(), popitem(), copy(), и update(), аналогичные методам стандартных словарей Python. Модуль collections.abc предоставляет абстрактный базовый класс MutableMapping, который помогает создавать эти методы на основе базового набора методов __getitem__(), __setitem__(), __delitem__(), и keys(). Изменяемые последовательности должны предоставлять методы append(), count(), index(), extend(), insert(), pop(), remove(), reverse() и sort(), подобно стандартным объектам списков Python. Наконец, типы последовательностей должны реализовывать сложение (т.е. конкатенацию) и умножение (т.е. повторение), определив методы __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]. Для типов последовательностей допустимыми ключами должны быть целые числа и объекты срезов. Обратите внимание, что специальное толкование отрицательных индексов (если класс хочет эмулировать тип последовательности) зависит от метода__getitem__(). Если ключ имеет неподходящий тип, может быть вызвано исключениеTypeError; если значение находится вне набора индексов для последовательности (после любого специального толкования отрицательных значений), должно быть вызвано исключениеIndexError. Для типов отображений, если ключ отсутствует (не находится в контейнере), должно быть вызвано исключениеKeyError.Примечание
Циклы
forожидают, что исключениеIndexErrorбудет вызвано для недопустимых индексов, чтобы корректно обнаружить конец последовательности.
-
object.__setitem__(self, key, value) -
Вызывается для реализации присваивания
self[key]. То же замечание, что и для__getitem__(). Это должно быть реализовано только для отображений, если объекты поддерживают изменения значений для ключей или добавление новых ключей, или для последовательностей, если элементы могут быть заменены. Те же исключения должны быть вызваны для неподходящих значений ключ, что и для метода__getitem__().
-
object.__delitem__(self, key) -
Вызывается для реализации удаления
self[key]. То же замечание, что и для__getitem__(). Это должно быть реализовано только для отображений, если объекты поддерживают удаление ключей, или для последовательностей, если элементы можно удалить из последовательности. Те же исключения должны быть вызваны для неподходящих значений ключ, что и для метода__getitem__().
-
object.__missing__(self, key) -
Вызывается методом
dict.__getitem__()для реализацииself[key]для подклассов dict, когда ключ отсутствует в словаре.
-
object.__iter__(self) -
Этот метод вызывается, когда требуется итератор для контейнера. Этот метод должен возвращать новый объект итератора, который может итерироваться по всем объектам в контейнере. Для отображений он должен итерироваться по ключам контейнера.
Объекты-итераторы также должны реализовывать этот метод; они должны возвращать себя. Дополнительную информацию об объектах-итераторах можно найти в разделе Типы итераторов.
-
object.__reversed__(self) -
Вызывается (если присутствует) встроенной функцией
reversed()для реализации обратной итерации. Он должен возвращать новый объект итератора, который итерируется по всем объектам в контейнере в обратном порядке.Если метод
__reversed__()не предоставлен, встроенная функцияreversed()использует протокол последовательности (__len__()и__getitem__()). Объекты, поддерживающие протокол последовательности, должны предоставлять__reversed__()только в том случае, если они могут предоставить реализацию, более эффективную, чем реализацияreversed().
Операторы проверки принадлежности (in и not in) обычно реализуются как итерация по контейнеру. Однако объекты контейнеров могут реализовать следующий специальный метод для более эффективной реализации, которая также не требует, чтобы объект был итерируемым.
-
object.__contains__(self, item) -
Вызывается для реализации операторов проверки принадлежности. Должен возвращать 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__(), вызывается методx.__add__(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__(), вызываетсяy.__rsub__(x), еслиx.__sub__(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). Если определённый метод не определён, расширенное присваивание использует обычные методы. Например, если x — экземпляр класса с методом__iadd__(),x += yэквивалентноx = x.__iadd__(y). В противном случае рассматриваютсяx.__add__(y)иy.__radd__(x), как и при оценкеx + y. В некоторых ситуациях расширенное присваивание может привести к непредвиденным ошибкам (см. Почему a_tuple[i] += [‘item’] вызывает исключение, когда сложение работает?), но это поведение является частью модели данных.Примечание
Из-за ошибки в механизме диспетчеризации для
**=, класс, который определяет__ipow__(), но возвращаетNotImplemented, не сможет перейти кx.__pow__(y)иy.__rpow__(x). Эта ошибка исправлена в Python 3.10.
-
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()и функцийmathtrunc(),floor()иceil(). Если параметр ndigits не передаётся в__round__(), все эти методы должны возвращать значение объекта, усечённое доIntegral(обычноint).Встроенная функция
int()обращается к__trunc__(), если ни__int__(), ни__index__()не определены.
3.3.9. Менеджеры контекста оператора with
Менеджер контекста — это объект, определяющий среду выполнения, которая должна быть установлена при выполнении оператора with. Менеджер контекста обрабатывает вход в желаемую среду выполнения и выход из неё для выполнения блока кода. Менеджеры контекста обычно вызываются с помощью оператора with (описанного в разделе Оператор with), но также могут использоваться путём прямого вызова их методов.
Типичные применения менеджеров контекста включают сохранение и восстановление различных типов глобального состояния, блокировку и разблокировку ресурсов, закрытие открытых файлов и т.д.
Для получения дополнительной информации о менеджерах контекста, см. Типы менеджеров контекста.
-
object.__enter__(self) -
Входит в среду выполнения, связанную с этим объектом. Оператор
withсвяжет возвращаемое значение этого метода с целевым(ими) объектами, указанными вasоператора, если таковые имеются.
-
object.__exit__(self, exc_type, exc_value, traceback) -
Выходит из среды выполнения, связанной с этим объектом. Параметры описывают исключение, которое вызвало выход из контекста. Если контекст был покинут без исключения, все три аргумента будут
None.Если передано исключение, и метод желает подавить исключение (т.е., предотвратить его распространение), он должен вернуть значение истины. В противном случае исключение будет обработано обычным образом при выходе из этого метода.
Обратите внимание, что методы
__exit__()не должны повторно генерировать переданное исключение; за это отвечает вызывающая сторона.
3.3.10. Поиск специальных методов
Для пользовательских классов неявные вызовы специальных методов гарантированы для корректной работы только если они определены в типе объекта, а не в словаре экземпляра. Это поведение причина того, почему следующий код вызывает исключение:
>>> 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() или asyncio.coroutine(), также являются awaitable, но они не реализуют __await__().
-
object.__await__(self) -
Должен возвращать итератор. Используется для реализации объектов, поддерживающих ожидание (awaitable). Например,
asyncio.Futureреализует этот метод для совместимости с выражениемawait.
Введено в версии 3.5.
См. также
PEP 492 для дополнительной информации об объектах, поддерживающих ожидание.
3.4.2. Объекты корутин
Объекты корутины являются awaitable объектами. Выполнение корутины можно контролировать, вызвав __await__() и перебирая результат. Когда корутина завершит выполнение и вернётся, итератор генерирует исключение StopIteration, и атрибут value исключения содержит возвращаемое значение. Если корутина вызывает исключение, оно передаётся итератором. Корутины не должны напрямую вызывать необработанные исключения StopIteration.
Корутины также имеют перечисленные ниже методы, аналогичные методам генераторов (см. Методы итератора генератора). Однако, в отличие от генераторов, корутины не поддерживают прямое итерацию.
Изменено в версии 3.5.2: Вызывать корутину более одного раза — это RuntimeError.
-
coroutine.send(value) -
Запускает или возобновляет выполнение корутины. Если значение равно
None, это эквивалентно продвижению итератора, возвращаемого__await__(). Если значение не равноNone, этот метод делегируется методуsend()итератора, который вызвал приостановку корутины. Результат (возвращаемое значение,StopIterationили другое исключение) аналогичен результату при переборе значения, возвращаемого__await__().
-
coroutine.throw(type[, value[, traceback]]) -
Вызывает указанное исключение в корутине. Этот метод делегируется методу
throw()итератора, который вызвал приостановку корутины, если такой метод существует. В противном случае исключение возникает в точке приостановки. Результат (возвращаемое значение,StopIterationили другое исключение) аналогичен результату при переборе значения, возвращаемого__await__(). Если исключение не обрабатывается в корутине, оно передаётся обратно вызывающему коду.
-
coroutine.close() -
Принудительно завершает корутину и закрывает её. Если корутина приостановлена, этот метод сначала делегирует метод
close()итератору, который вызвал приостановку корутины, если такой метод существует. Затем он вызывает исключениеGeneratorExitв точке приостановки, заставляя корутину немедленно завершить свою работу. Наконец, корутина помечается как завершённая, даже если она никогда не запускалась.Объекты корутин автоматически закрываются в соответствии с указанным процессом при уничтожении.
3.4.3. Асинхронные итераторы
Асинхронный итератор может вызывать асинхронный код в своём методе __anext__.
Асинхронные итераторы можно использовать в инструкции async for.
-
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.__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__()имеют специальную обработку; другие всё ещё будут генерироватьTypeError, но могут сделать это, полагаясь на поведение, чтоNoneне является вызываемым. -
3 -
«Не поддерживает» здесь означает, что у класса нет такого метода, или метод возвращает
NotImplemented. Не устанавливайте метод вNone, если вы хотите принудительно перейти к отражённому методу правого операнда — это вместо этого будет иметь противоположный эффект, чётко блокируя такой переход. -
4 -
Для операндов одного типа предполагается, что если неуказанный метод, например,
__add__(), не выполняется, то операция в целом не поддерживается, поэтому отражённый метод не вызывается.
© 2001–2022 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.8/reference/datamodel.html