3. Модель данных¶
3.1. Объекты, значения и типы¶
Объекты — это Python абстракции для данных. Все данные в Python программе представлены объектами или связями между объектами. (В некотором смысле, и в соответствии с моделью фон Неймана «Хранимого программного компьютера», — код также представлен объектами).
Каждый объект имеет идентификатор, тип и значение. После создания объекта его
идентификатор никогда не изменяется; его можно рассматривать как адрес
объекта в памяти. Оператор is
сравнивает идентичность двух объектов;
функция id()
возвращает целое число, представляющее его идентификатор.
Детали реализации CPython: Для CPython, id(x)
- это адрес в памяти, где хранится x
.
Тип объекта определяет операции, которые поддерживает объект (например, «есть
ли у него длина?»), а также определяет возможные значения для объектов этого типа.
Функция type()
возвращает тип объекта (который является тоже объектом).
Как его идентификатор, 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
. Используется для обозначения отсутствия значения во многих ситуациях, например, он возвращается функцией, которые ничего явно не возвращают. Его булево значение — False.- NotImplemented
Данный тип имеет единственное значение. Существует единственный объект с этим значением. Доступ к этому объекту получают через встроенное имя
NotImplemented
. Числовой методы и методы расширенного сравнения, должны возвратить это значение, если они не реализуют операцию для предоставленных операндов. (Интерпретатор тогда попробует выполнить выдуманную операцию или некоторых другой запасной вариант, в зависимости от оператора). Его булево значение — False.Дополнительные сведения см. в разделе Реализация арифметических операций.
- Многоточие
У данного типа единственное значение. Существует один объект с этим значением. Доступ к этому объекту осуществляется через литерал
...
или встроенное имяEllipsis
. Его булево значение — True.numbers.Number
Они создаются числовыми литералами и возвращаются в виде результатов арифметических операторов и встроенными арифметическими функциями. Числовые объекты — неизменяемы; после создания их значение никогда не меняется. Python числа, конечно, сильно связаны с математическими числами, но с учетом ограничений числового представления в компьютерах.
Строковые представления числовых классов, вычисленные
__repr__()
и__str__()
имеют следующие свойства:- Это действительные числовые литералы, которые при передаче в их конструктор класса, создают объект, имеющий исходное числовое значение.
- По возможности представление выполняется по основанию 10.
- Начальные нули, возможно, за исключением одного нуля перед десятичной точкой, не отображаются.
- Конечные нули, возможно, за исключением одного нуля после десятичной точки, не отображаются.
- Знак отображается только тогда, когда число отрицательное.
Python различает целые числа, числа с плавающей запятой и комплексные числа:
numbers.Integral
Они представляют элементы из математического набора целых чисел (положительные и отрицательные).
Существует два типа целых чисел:
Целые числа (
int
)Они представляют числа в неограниченном диапазоне, зависящем только от доступной (виртуальной) памяти. Для операций сдвига и маски предполагается двоичное представление, а отрицательные числа представлены в варианте дополнения 2, что создаёт иллюзию бесконечной строки знаковых битов, простирающихся влево.- Логические (
bool
) Они представляют булевы значения Ложь и Истина. Два объекта, представляющие значения
False
иTrue
, являются единственными возможными логическими объектами. Логический тип является подтипом целочисленного типа, и логические значения ведут себя как значения 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 нет типа c:type:char; вместо этого, каждая кодовая точка в строке представлена как строковый объект длиной1
. Встроенная функцияord()
преобразует кодовую точку из строки в целое число в диапазоне0 - 10FFFF
;chr()
преобразовывает целое число в диапазоне0 - 10FFFF
к соответствующему строковому объекту длины1
.str.encode()
может использоваться, чтобы преобразоватьstr
вbytes
с использованием заданной текстовой кодировки, аbytes.decode()
может использоваться, для достижения противоположного.- Кортежи
Элементы кортежа - это произвольные объекты Python. Кортежи из двух или более элементов формируются списками выражений, разделенными запятыми. Кортеж из одного элемента («синглетон») можно сформировать, добавив запятую к выражению (выражение само по себе не создает кортеж, так как круглые скобки должны использоваться для группировки выражений). Пустой кортеж может быть сформирован пустой парой скобок.
- Байты
Байтовый объект — неизменяемый массив. Элементы представляют собой 8-битные байты, представленные целыми числами в диапазоне 0 <= x <256. Байтовые литералы (например
b'abc'
) и встроенный конструкторbytes()
могут использоваться для создания байтовых объектов. Кроме того, байтовые объекты могут декодироваться в строки через методdecode()
.
- Изменяемые последовательности
Изменяемые последовательности могут быть изменены после их создания. Обозначения индексирования и нарезки могут использоваться как цель операторов присвоения и
del
(удаления).В настоящее время существует два внутренних изменяемых типов последовательностей:
- Списки
Элементы списка являются произвольными Python объектами. Списки формируются путем помещения разделенного запятыми списка выражений в квадратные скобки. (Обратите внимание, что для формирования списков длиной 0 или 1 не требуется особых случаев).
- Байтовые массивы
Объект байтовых массивов является изменяемым массивом. Они создаются встроенным конструктором
bytearray()
. Помимо возможности изменения (и, следовательно, нехэшируемыми), байтовые массивы предоставляют тот же интерфейс и функциональность, что и неизменяемыеbytes
объекты.
Дополнительный модуль
array
предоставляет дополнительный пример изменяемого типа последовательности, как и модульcollections
.
- Типы множеств
Они представляют собой неупорядоченные конечные наборы уникальных неизменяемых объектов. Таким образом, они не могут быть проиндексированы каким-либо нижним индексом. Однако по ним можно итерироваться, а встроенная функция
len()
возвращает количество элементов в множестве. Обычно множества используются для быстрой проверки членства, удаление дубликатов из последовательности и вычисления математических операций, таких как пересечение, объединение, разность и симметричная разность.Для элементов множеств применяются те же правила неизменяемости, что и для ключей словаря. Обратите внимание, что числовые типы подчиняются нормальным правилам для числового сравнения: если два числа признаются равными (например,
1
и1.0
), в множестве может содержаться только одно из них.В настоящее время существует два внутренних типа множеств:
- Множества
Они представляют собой изменяемое множество. Они создаются встроенным конструктором
set()
и могут быть изменены несколькими методами, такими какadd()
.- Замороженные множества
Они представляют неизменяемое множество. Они создаются встроенным конструктором
frozenset()
. Так как frezenset является неизменным и хэшируемым, его можно снова использовать как элемент другого множества, или как словарный ключ.
- Отображения
Они представляют собой конечные наборы объектов, индексированных произвольными множествами индексов. Индексное обозначение
a[k]
выбирает элемент по индексуk
из отображенияa
; это может использоваться в выражениях и как цель присвоений или операторовdel
. Встроенная функцияlen()
возвращает количество элементов в отображении.В настоящее время существует единственный внутренний тип отображения:
- Словари
Они представляют собой конечные множества объектов, индексированных почти произвольными значениями. Единственными типами значений, не приемлемых в качестве ключей, являются значения, содержащими списки или словари или другие изменяемые типы, которые сравниваются по значения, а не по идентификатору объекта ,— причина в том, что эффективная реализация словарей требует, чтобы хэш-значение ключа осталось постоянным. Числовые типы, используемый для ключей подчиняются обычным правилам для числового сравнения: если два числа вычисляются равными (например,
1
и1.0
) тогда, они могут использоваться взаимозаменяемо, для индексации одного и того же словарного элемента.Словари сохраняют порядок вставки, это означает, что ключи будут создаваться в том же порядке, они были добавлены последовательно в словаре. Замена существующего ключа не меняет порядок, однако удаление ключа и повторная вставка добавит его в конец вместо того, чтобы сохранить его старое место.
Словари изменяемые; они могут быть созданы с помощью
{...}
нотации (см. раздел Отображение словаря).Модули расширения
dbm.ndbm
иdbm.gnu
предоставляют дополнительные примеры типов отображений, как и модульcollections
.Изменено в версии 3.7: Словари не сохраняли порядок вставки в версиях Python до 3.6. В CPython 3.6 порядок вставки был сохранён, но в то время он считался деталью реализации, а не гарантией языка.
- Вызываемые типы
Типы, к которым можно применить операцию вызова функции (см. раздел Вызываемые):
- Определяемые пользователем функции
Определяемый пользователем объект функции создается определением функции (см. раздел Определения функции). Он должен вызываться со списком аргументов, содержащим то же количество элементов, что и список формальных параметров функции.
Специальные атрибуты:
Атрибут Значение __doc__
Строка документации функции или None
, если она недоступна; не наследуется подклассами.Перезаписываемый __name__
Название функции. Перезаписываемый __qualname__
Квалифицированное имя функции.
Добавлено в версии 3.3.
Перезаписываемый __module__
Имя модуля в котором определена функция или None
, если недоступно.Перезаписываемый __defaults__
Кортеж, содержащий аргумент по умолчанию, значения тех же аргументов, у которых по умолчанию или None
, если ни у каких аргументов нет значения по умолчанию.Перезаписываемый __code__
Объект кода, представляющий тело скомпилированной функции. Перезаписываемый __globals__
Ссылка на словарь, содержащая глобальные переменные функции. Др. словами — это глобальное пространство имён модуля, в котором была определена функция. Только для чтения __dict__
Пространство имён, поддерживающее произвольные атрибуты функции. Перезаписываемый __closure__
None
или кортеж ячеек, которые содержат биндинги для свободных переменных функции. См. ниже для получения информации об атрибутеcell_contents
.Только для чтения __annotations__
dict, содержащий аннотации параметров. Ключи dict - названия параметров и 'return'
для возвращения аннотации, если передан.Перезаписываемый __kwdefaults__
dict содержащий параметры по умолчанию только для ключевых параметров. Перезаписываемый Большинство атрибутов, помеченных как «Перезаписываемый», проверяют тип назначенного значения.
Объекты функции также поддерживают получение и установку произвольных атрибутов, которые могут использоваться, например, для присоединения метаданных к функциям. Для получения и установки таких атрибутов используется обычная точечная нотация атрибутов. Обратите внимание, что текущая реализация поддерживает только атрибуты функций для пользовательских функций. Атрибуты функций встроенных функций могут поддерживаться в будущем.
Объект ячейки имеет атрибут
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__()
асинхронного итератора вернёт ожидаемый, который при ожидании будет выполняться до тех пор, пока не предоставит значение с помощью выражения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 по адресу.Когда ссылка на атрибут класса (например, для класса
C
) возвращает объект метода класса, она преобразуется в объект метода экземпляра, атрибут__self__
которого равенC
. Когда она возвращает объект статического метода, то преобразуется в объект, обернутый статическим методом объекта. Посмотрите раздел Реализация дескрипторов, чтобы узнать о другом способе, в котором атрибуты полученные из класса, могут отличаться от фактически содержащихся в его__dict__
.Присвоение атрибутам класса обновляет словарь класса, а не словарь базового класса.
Объект класса можно вызвать (см. выше) для получения экземпляра класса (см. ниже).
Специальные атрибуты:
__name__
- имя класса;__module__
- имя модуля, в котором был определен класс;__dict__
- словарь, содержащий пространство имён класса;__bases__
- кортеж, содержащий базовые классы в порядке их появления в списке базовых классов;__doc__
- строка документации класса илиNone
, если она не определена;__annotations__
(необязательный) - словарь, содержащий аннотации переменных, собранные во время выполнения тела класса.- Экземпляры классов
Экземпляр класса создаётся путём вызова объекта класса (см. выше). У экземпляра класса есть пространство имён, реализованное в виде словаря, являющийся первым местом, в котором ищутся ссылки на атрибуты. Если атрибут там не найден, а экземпляр класса имеет атрибут с таким именем, поиск продолжается по атрибутам класса. Если обнаружен атрибут класса, являющийся объектом определяемой пользователем функции, он преобразуется в объект метода экземпляра, атрибут
__self__
которого является экземпляром. Также преобразуются объекты статических методов и методов класса; см. выше в разделе «Классы». См. раздел Реализация дескрипторов чтобы узнать о другом способе, в котором атрибуты класса, полученные через его экземпляры, могут отличаться от объектов, фактически хранящихся в__dict__
класса. Если атрибут класса не найден, а в объекте класса есть метод__getattr__()
, то вызывается этот метод для выполнения поиска.Назначение и удаление атрибутов обновляют словарь экземпляра, а не словарь класса. Если класс имеет метод
__setattr__()
или__delattr__()
, он вызывается вместо прямого обновления словаря сущность.Экземпляры классов могут притворяться числами, последовательностями или отображениями, если у них есть методы с определенными специальными именами. См. раздел Имена специальных методов.
Специальные атрибуты:
__dict__
- словарь атрибутов;__class__
- класс экземпляра.- I/O объекты (также известные как файловые объекты)
Файловый объект представляет собой открытый файл. Для создания файловых объектов доступны различные ярлыки: встроенная функция
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
устанавливается, если функция была собрана с включенным будущим делением (future division); биты0x10
и0x1000
использовались в более ранних версиях Python.Другие биты в
co_flags
зарезервированы для внутреннего использования.Если объект кода представляет функцию, первый элемент в
co_consts
- строка документации функции илиNone
, если не определено.
- Объекты фрейма
Объекты фрейма представляют собой фреймы выполнения. Они могут встречаться в объектах трассировки (см. ниже), и также передаются зарегистрированным функциям трассировки.
Специальные атрибуты только для чтения:
f_back
- относится к предыдущему фрейму стека (по направлению к вызывающему) илиNone
, если это нижний фрейм стека;f_code
- объект кода, выполняемый в этом фрейме;f_locals
- словарь, используемый для поиска локальных переменных;f_globals
- используется для глобальных переменных;f_builtins
- используется для встроенных (внутренних) имен;f_lasti
дает точную инструкцию (это индекс в строке байт-кода объекта кода).Специальные записываемые атрибуты:
f_trace
, если неNone
, является функцией, вызываемой для различных событий во время выполнения кода (используется отладчиком). Обычно событие запускается для каждой новой исходной строки - это можно отключить, установив для параметраf_trace_lines
значениеFalse
.Реализации могут позволить запрашивать события для каждого кода операции, установив
f_trace_opcodes
вTrue
. Обратите внимание, что это может привести к неопределенному поведению интерпретатора, если исключения, порожденные функцией трассировки, уйдут в отслеживаемую функцию.f_lineno
- текущий номер строки фрейма — запись в него изнутри функции трассировки переходит к данной строке (только для самой нижнего фрейма). Отладчик может реализовать команду Jump (также известную как установка следующего оператора), записав в 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_next
- это следующий уровень в трассировке стека (по направлению к фрейму, в котором произошло исключение) илиNone
, если нет следующего уровня.Изменено в версии 3.7: Объекты трэсебэка могут явно созданы из кода Python, а атрибут
tb_next
существующих экземпляров может быть обновлен.- Объекты нарезки (slice)
Объекты нарезки используются для представления срезов для методы
__getitem__()
. Они также создаются встроенной функциейslice()
.Специальные атрибуты только для чтения:
start
- нижняя граница;stop
- верхняя граница;step
- значение шага; каждый из нихNone
, если он не указан. Эти атрибуты могут иметь любой тип.Объекты нарезки поддерживают один метод:
-
slice.
indices
(self, length)¶ Данный метод принимает один целочисленный аргумент length и вычисляет информацию о срезе, который объект среза будет определять, если применить к последовательности элементов length. Возвращает кортеж из трёх целых чисел; соответственно это индексы start и stop и длина step или шаг среза. Индексы с отсутствующими или выходящими за границы индексами обрабатываются таким же образом, как и обычные срезы.
-
- Объекты статического метода
- Объекты статических методов позволяют предотвратить преобразование объектов
функций в объекты методов, приведенные выше. Объект статического
метода — это обёртка любого другого объекта, обычно определяемого
пользователем объекта метода. Когда объект статического метода извлекается
из класса или экземпляра класса, фактически возвращаемый объект является
обернутым объектом, который не подлежит дальнейшему преобразованию.
Объекты статических методов сами по себе не вызываются, хотя объекты, которые
они обёртывают, обычно таковы. Объекты статических методов создаются
встроенным конструктором
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__()
для его настройки)__init__()
не может возвращать значения, отличные отNone
; это приведет к появлению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 выражение, которое можно использовать для воссоздания объекта с тем же значением (с соответствующей среде). Если это невозможно, необходимо вернуть строку формы<...какое-то полезное описание...>
. Возвращаемое значение должно быть строковым объектом. Если класс определяет__repr__()
, но не__str__()
, то__repr__()
также используется, когда требуется «неофициальное» представление строки сущности того класса.Обычно это используется для отладки, поэтому важно, чтобы представление было насыщенным и однозначным.
-
object.
__str__
(self)¶ Вызывается
str(object)
и встроенными функциямиformat()
иprint()
для вычисления «неофициального» или красиво печатаемого строкового представления объекта. Возвращаемое значение должно быть объектом строки.Метод отличается от
object.__repr__()
, в котором нет никакого ожидания, что__str__()
возвращают допустимое Python выражение: можно использовать более удобное или краткое представление.Реализация по умолчанию, определяемая
object
встроенного типа, вызываетobject.__repr__()
.
-
object.
__bytes__
(self)¶ Вызывается функция bytes для вычисления представления объекта в виде байтовой строки. При этом должен быть возвращен объект
bytes
.
-
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()
для значения, чтобы определить, является ли результат истинным или ложный.По умолчанию объект реализующий
__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__()
объекта до размера c:type: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 == y
подразумевает как тоx is y
, так иhash(x) == hash(y)
.Класс, который переопределяет
__eq__()
и не определяет__hash__()
, будет содержать для своего__hash__()
неявное значение вNone
. Когда для метода__hash__()
класса будет установлено значениеNone
, сущности класса вызовут соответствующееTypeError
, когда программа попытается получить их хэш-значение, а также будет правильно идентифицирована как нехэшируемый при проверкеisinstance(obj, collections.abc.Hashable)
.Если класс переопределяет
__eq__()
, то он должен сохранить реализацию__hash__()
родительского класса,- об этом интерпретатору нужно сказать явно, установив__hash__ = <ParentClass>.__hash__
.Если класс, который не переопределяет
__eq__()
, хочет подавить поддержку хэширования, он должен включить__hash__ = None
в определение класса. Класс, определяющий свой собственный__hash__()
, который явно вызываетTypeError
, будет неправильно идентифицирован как хэшируемый вызовомisinstance(obj, collections.abc.Hashable)
.Примечание
По умолчанию значения
__hash__()
объектов str и bytes «посолены» с непредсказуемым случайным значением. Хотя они остаются постоянными в рамках отдельного процесса Python, их нельзя предсказать между повторными вызовами Python.Это предназначено для обеспечения защиты от отказа в обслуживании, вызванного тщательно выбранными входными данными, которые используют худшую производительность вставки в dict(сложность O(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
, потому что name не атрибут сущности или атрибут в дереве классов дляself
; либо__get__()
свойства name вызывает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)¶ Вызывается при попытке присвоения атрибута. Вызывается вместо обычного механизма (т.е. сохранения значения в словаре сущности). name - название атрибута, value - значение, которое будет ему присвоена.
Если
__setattr__()
хочет присвоить атрибут экземпляра, он должен вызвать метод базового класса с тем же именем, например,object.__setattr__(self, name, value)
.Для присвоения к определенным чувствительным атрибутам вызывается событие аудита
object.__setattr__
с аргументамиobj
,name
иvalue
.
-
object.
__delattr__
(self, name)¶ Подобен
__setattr__()
, но удаляет атрибут вместо присвоения. Это должно быть реализовано только в том случае, еслиdel obj.name
имеет значение для объекта.Для удаления определенных чувствительных атрибутов вызывается событие аудита
object.__getattr__
с аргументами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’а поддерживают данную спецификацию; однако, вероятно, некоторые сторонние инструменты содержат дескрипторы, которые требуют обоих аргументов. Собственная реализация Python’а__getattribute__()
, всегда передает оба аргумента независимо от того, требуются они или нет.
-
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)
. - Супер-привязка,
- Если
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()
реализована как дескриптор данных. Соответственно,
экземпляры не могут переопределять поведение 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__. Попытки присвоить имя переменной,
не указанной в списке, вызывают ошибку
AttributeError
. Если требуется динамическое присвоение новых переменных, добавьте'__dict__'
к последовательности строк в объявлении __slots__. - Без переменной __weakref__ для каждого случая классы, определяющие
__slots__, не поддерживают слабые ссылки на его сущности. Если требуется
слабая опорная поддержка, добавьте
'__weakref__'
в последовательность строки в объявлении __slots__. - __slots__ реализуются на уровне класса путем создания дескрипторов (Реализация дескрипторов) для каждого имени переменной. В результате атрибуты класса не могут использоваться для установки значений по умолчанию для переменных определенных __slots__ экземпляра; в противном случае атрибут класса перезаписывает назначение дескриптора.
- Действие объявления __slots__ не ограничивается классом, в котором оно определено. __slots__, объявленные у родителей, доступны в дочерних классах. Однако дочерние подклассы получат __dict__ и __weakref__, если они также не определят __slots__ (который должен содержать только имена любых дополнительных слотов).
- Если класс определяет слот, также определенный в базовом классе, переменная экземпляра, определенная слотом базового класса, становится недоступна (кроме как путем получения ее дескриптора непосредственно из базового класса). Это делает значение программы неопределенным. В будущем может быть добавлена проверка, для предотвращения этого.
- Непустой __slots__ не работает для классов, производных от встроенных типов
переменной длины, таких как
int
,bytes
иtuple
. - Любой нестроковый итерируемый объект может быть присвоен в __slots__. Могут также использоваться сопоставления; однако, в будущих значениях, соответствующих каждому ключу, может быть присвоено особое значение.
- Присвоение __class__ работает только в том случае, если оба класса имеют одинаковый __slots__.
- Можно использовать множественное наследование с несколькими слотированными
родительскими классами, но только один родитель может иметь атрибуты,
созданные слотами (другие основы должны иметь пустые макеты слотов). Нарушения
вызывают
TypeError
. - Если используется итератор для __slots__ , то дескриптор создается для каждого значения итератора. Однако атрибут __slots__ будет пустым итератором.
3.3.3. Настройка создания класса¶
Каждый раз, когда класс наследуется от другого класса, для этого класса
вызывается __init_subclass__. Таким образом, возможно написать классы, которые изменяют
поведение подклассов. Это тесно связано с декораторами классов, но там, где
декораторы классов влияют только на применяемый класс.
__init_subclass__
применяется исключительно к будущим
подклассам класса, определяющего метод.
-
classmethod
object.
__init_subclass__
(cls)¶ Метод вызывается всякий раз, когда содержащий класс является подклассом. cls — это новый подкласс. Если он определён как обычный метод экземпляра, этот метод неявно преобразуется в метод класса.
Ключевые аргументы, которые передаются новому классу, передаются родительскому классу
__init_subclass__
. Для совместимости с другими классами, использующими__init_subclass__
, необходимо извлечь необходимые ключевые аргументы и передать остальные в базовый класс. Например:class Philosopher: def __init_subclass__(cls, /, default_name, **kwargs): super().__init_subclass__(**kwargs) cls.default_name = default_name class AustralianPhilosopher(Philosopher, default_name="Bruce"): pass
Реализация по умолчанию
object.__init_subclass__
ничего не делает, но вызывает ошибку, если он вызывается с любыми аргументами.Примечание
Подсказка метакласса
metaclass
используется остальной частью механизма типов и никогда не передаётся в реализации__init_subclass__
. Фактический метакласс (а не явная подсказка) может быть доступна какtype(cls)
.Добавлено в версии 3.6.
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__
, чтобы
класс был правильно инициализирован. В противном случае в Python 3.8 возникнет ошибка
RuntimeError
.
При использовании 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)¶ Возвращает истину, если instance нужно считать (прямой или косвенной) сущностью класса. Если определено, вызывается для реализации
isinstance(instance, class)
.
-
class.
__subclasscheck__
(self, subclass)¶ Возвращает истину, если subclass нужно считать (прямым или косвенным) подклассом класса. Если определено, вызывается для реализации
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 - поддержка ядром типизации модулей и универсальных типов
3.3.6. Эмуляция вызываемых объектов¶
-
object.
__call__
(self[, args...])¶ Вызывается, когда сущность вызывается как функция; если этот метод определён,
x(arg1, arg2, ...)
примерно преобразуется вx.__call__(arg1, arg2, ...)
.
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__()
. Если key имеет неподходящий тип, может быть возникнуть ошибкаTypeError
; если значение выходит за пределы набора индексов для последовательности (после любой специальной интерпретации отрицательных значений), следует вызватьIndexError
. Для типов сопоставления, если key отсутствует (не в контейнере), следует вызватьKeyError
.Примечание
Циклы
for
ожидают, что будет вызваноIndexError
для недопустимых индексов, чтобы обеспечить правильное обнаружение конца последовательности.
-
object.
__setitem__
(self, key, value)¶ Вызывается для реализации назначения
self[key]
. То же примечание, что и для__getitem__()
. Должен быть реализован только для сопоставлений, если объекты поддерживают изменения значений ключей или если можно добавить новые ключи, или для последовательностей, если элементы могут заменяться. Для неправильных значений key следует создать те же исключения, что и для__getitem__()
метода.
-
object.
__delitem__
(self, key)¶ Вызывается для выполнения удаления
self[key]
. То же примечание, что и для__getitem__()
. Должен быть реализован только для сопоставлений, если объекты поддерживают удаление ключей, или для последовательностей, если элементы могут быть удалены из последовательности. Для неправильных значений key следует создать те же исключения, что и для метода__getitem__()
.
-
object.
__missing__
(self, key)¶ Вызывается
dict
.__getitem__()
для реализации функцииself[key]
для подклассов dict, если ключ отсутствует в словаре.
-
object.
__iter__
(self)¶ Метод вызывается, когда для контейнера требуется итератор. Данный метод должен возвратить новый объект итератора, который может перебрать все объекты в контейнере. Для сопоставлений он должен перебирать ключи контейнера.
Объекты-итераторы также должны реализовать данный метод; они обязаны вернуться сами. Дополнительные сведения об объектах-итераторах см. в разделе Типы итераторов.
-
object.
__reversed__
(self)¶ Вызывается (если присутствует) встроенной функцией
reversed()
для реализации обратной итерации. Он должен вернуть новый объект итератора, который итерируется по всем объектам в контейнере в обратном порядке.Если метод
__reversed__()
не предоставлен, то встроеннаяreversed()
вернётся к использованию протокола последовательности (__len__()
и__getitem__()
). Объекты, поддерживающие протокол последовательности, должны предоставлять__reversed__()
только в том случае, если они могут обеспечить более эффективную реализацию, чем та, которая предоставляетreversed()
.
Операторы проверки членства (in
и not in
) обычно
реализуются как итерация через контейнер. Однако объекты-контейнеры могут
поставлять следующий специальный метод более эффективной реализацией,
который также не требует, чтобы объект был итерируемым.
-
object.
__contains__
(self, item)¶ Вызывается для реализации операторов проверки членства. Должен возвращать истину, если item находится в self, иначе ложь. Для объектов-отображения следует рассматривать ключи отображения, а не пар ключ-значение.
Для объектов, которые не определяют
__contains__()
, тест членства сначала пытается выполнить итерацию через__iter__()
, затем старый протокол итерации последовательности через__getitem__()
, см. раздел справочника по языку.
3.3.8. Эмуляция числовых типов¶
Следующие методы могут быть определены для имитации числовых объектов. Методы, соответствующие операциям, которые не поддерживаются типом реализованных чисел (например, побитовые операции для нецелых чисел), следует оставить неопределёнными.
-
object.
__add__
(self, other)¶ -
object.
__sub__
(self, other)¶ -
object.
__mul__
(self, other)¶ -
object.
__matmul__
(self, other)¶ -
object.
__truediv__
(self, other)¶ -
object.
__floordiv__
(self, other)¶ -
object.
__mod__
(self, other)¶ -
object.
__divmod__
(self, other)¶ -
object.
__pow__
(self, other[, modulo])¶ -
object.
__lshift__
(self, other)¶ -
object.
__rshift__
(self, other)¶ -
object.
__and__
(self, other)¶ -
object.
__xor__
(self, other)¶ -
object.
__or__
(self, other)¶ Данные методы вызываются для реализации бинарных арифметических операций (
+
,``-, ``*
,@
,/
,//
,%
,divmod()
,pow()
,**
,<<
,>>
,&
,^
,|
). Например, чтобы вычислить выражениеx + y
, где x сущность класса у которого есть метод__add__()
, вызываетсяx.__add__(y)
. Метод__divmod__()
должен быть эквивалентен использованию__floordiv__' и :meth:`__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»] создает исключение при работе сложения?), но на самом деле такое поведение является частью модели данных.
-
object.
__neg__
(self)¶ -
object.
__pos__
(self)¶ -
object.
__abs__
(self)¶ -
object.
__invert__
(self)¶ Вызывается для реализации унарных арифметических операций (
-
,+
,abs()
и~
).
-
object.
__complex__
(self)¶ -
object.
__int__
(self)¶ -
object.
__float__
(self)¶ Вызывается для реализации встроенных функций
complex()
,int()
иfloat()
. Возвращает значение соответствующего типа.
-
object.
__index__
(self)¶ Вызывается для реализации
operator.index()
и всякий раз, когда Python должен без потерь преобразовать числовой объект в целочисленный объект (например, при нарезке или во встроенных функцияхbin()
,hex()
иoct()
). Присутствие этого метода указывает на то, что числовой объект имеет целочисленный тип. Должен возвращать целое число.Если
__int__()
,__float__()
и__complex__()
не определены, то соответствующие встроенные функцииint()
,float()
иcomplex()
возвращаются к__index__()
.
-
object.
__round__
(self[, ndigits])¶ -
object.
__trunc__
(self)¶ -
object.
__floor__
(self)¶ -
object.
__ceil__
(self)¶ Вызывается для реализации встроенной функции
round()
и функцийmath
trunc()
,floor()
иceil()
. Если ndigits не передан к__round__()
, все эти методы должны возвратить значение объекта, усеченного доIntegral
(как правило,int
).Если
__int__()
не определено, то встроенная функцияint()
возвращается к__trunc__()
.
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("Вызван метакласс getattribute")
... return type.__getattribute__(*args)
...
>>> class C(object, metaclass=Meta):
... def __len__(self):
... return 10
... def __getattribute__(*args):
... print("Вызван класс getattribute")
... return object.__getattribute__(*args)
...
>>> c = C()
>>> c.__len__() # Явный поиск через сущность
Class getattribute invoked
10
>>> type(c).__len__(c) # Явный поиск через тип
Metaclass getattribute invoked
10
>>> len(c) # Неявный поиск
10
Обход механизма __getattribute__()
таким образом предоставляет значительные
возможности для оптимизации скорости в интерпретаторе, за счёт некоторой
гибкости в обработке специальных методов (специальный метод должен быть установлен
в самом объекте класса, чтобы его можно было последовательно вызывать из интерпретатора).
3.4. Корутины¶
3.4.1. Await (ожидаемые) объекты¶
Ожидаемый объект обычно реализует метод __await__()
. Объекты
корутины, возвращенные из функций async def
— ожидаемые.
Примечание
Генератор итератор объекты возвращаемые генераторами, декорированных types.coroutine()
или
asyncio.coroutine()
также ожидаемые, но они не реализуют __await__()
.
-
object.
__await__
(self)¶ Должен вернуть итератор. Следует использовать для реализации ожидаемых объектов. Например,
asyncio.Future
реализует данный метод, для совместимости сawait
выражением.
Добавлено в версии 3.5.
См.также
PEP 492 для получения дополнительной информации об ожидающих объектах.
3.4.2. Объекты корутины¶
Объекты корутины являются ожидающими
объектами. Выполнением корутиной можно
управлять вызовом __await__()
и итерацией по результату. Когда корутина
завершает выполнение и возвращает результат, итератор вызывает StopIteration
, а атрибут
value
исключения содержит возвращаемое значение. Если корутина вызывает
исключение, оно распространяется итератором. Корутины не должны напрямую вызывать
необработанные StopIteration
исключения.
Корутины также имеют перечисленные ниже методы, которые аналогичны методам генераторов (см. Методы генератора-итератора). Однако, в отличие от генераторов, корутины не поддерживают непосредственную итерацию.
Изменено в версии 3.5.2: Исключение RuntimeError
ожидает на корутине более одного раза.
-
coroutine.
send
(value)¶ Запускает или возобновляет выполнение корутины. Если value -
None
, это эквивалентно продвижению итератора, возвращенного__await__()
. Если value неNone
, этот метод делегируется методуsend()
итератора, который вызвал приостановку корутины. Результат (возвращаемое значение,StopIteration
или другое исключение) такой же, как при итерации возвращаемого значения__await__()
, описанному выше.
-
coroutine.
throw
(type[, value[, traceback]])¶ Вызывает указанное исключение в корутине. Данный метод делегирует метод
throw()
итератора, который вызвал приостановку корутины, если у неё есть такой метод. Иначе вызывается исключение в точке приостановки. Результат (возвращаемое значение,StopIteration
или другое исключение) такой же, как и при итерации возвращаемого значения__await__()
, описанному выше. Если исключение не перехвачено в корутине, оно распространяется обратно к вызывающей стороне.
-
coroutine.
close
()¶ Заставляет корутину очистить себя и выйти. Если корутина приостановлена, этот метод сначала делегирует метод
close()
итератора, который вызвал приостановку корутины, если у неё есть такой метод. Затем вызываетсяGeneratorExit
в точке приостановки, заставляя корутину немедленно очиститься. В завершении, корутина помечается как завершившая выполнение, даже если она никогда не запускалась.Объекты корутины автоматически закрываются с помощью вышеописанного процесса, когда они собираются уничтожиться.
3.4.3. Асинхронные итераторы¶
Асинхронный итератор может вызывать асинхронные код в своём методе
__anext__
.
Асинхронные итераторы можно использовать в операторе async for
.
-
object.
__aiter__
(self)¶ Должен возвратить объект асинхронного итератора.
-
object.
__anext__
(self)¶ Должен возвратить ожидаемый, приводящий к следующему значению итератора. Должен вызвать ошибку
StopAsyncIteration
, при окончании итерации.
Пример асинхронного итерируемого объекта:
class Reader:
async def readline(self):
...
def __aiter__(self):
return self
async def __anext__(self):
val = await self.readline()
if val == b'':
raise StopAsyncIteration
return val
Добавлено в версии 3.5.
Изменено в версии 3.7: До Python 3.7 __aiter__
мог вернуть ожидаемый, который разрешался
асинхронным итератором.
Начиная с Python 3.7, __aiter__
должен возвращать объект асинхронного
итератора. Возвращение чего-либо другого приведёт к ошибке TypeError
.
3.4.4. Асинхронные контекстные менеджеры¶
Асинхронный менеджер контекста — это контекстный менеджер, который может приостановить
выполнение в своих методах __aenter__
и __aexit__
.
Асинхронные менеджеры контекста могут использоваться в операторе async with
.
-
object.
__aenter__
(self)¶ Семантически похож на
__enter__()
, с той лишь разницей, что он должен возвращать ожидаемый объект.
-
object.
__aexit__
(self, exc_type, exc_value, traceback)¶ Семантически похож на
__exit__()
, с той лишь разницей, что он должен возвращать ожидаемый объект.
Пример асинхронного класса менеджера контекста:
class AsyncContextManager:
async def __aenter__(self):
await log('Вход в контекст')
async def __aexit__(self, exc_type, exc, tb):
await log('Выход из контекста')
Добавлено в версии 3.5.
Сноски
[1] | В некоторых случаях возможно изменить тип объекта при определенных контролируемых условиях. Как правило, это не лучшая идея, поскольку при неправильном обращении может привести к очень странному поведению. |
[2] | У методов __hash__() , __iter__() , __reversed__() и
__contains__() есть для этого специальная обработка; другие по-прежнему будут
вызывать TypeError , но могут сделать это, полагаясь на поведение, что
None не вызывается. |
[3] | «Не поддерживает» здесь означает, что класс не имеет такого метода или
метод возвращает NotImplemented . Не устанавливайте для метода значение None ,
если требуется принудительно использовать метод, отраженный в правом операнде.
Вместо этого будет явно блокироваться такой метод. |
[4] | Для операндов того же типа предполагается, что если неотражённый метод
(например, __add__() ) завершается неудачно, то общая операция не
поддерживается, поэтому отраженный метод не вызывается. |