Документация Python неофициальный перевод
Содержание страницы

3. Модель данныхData model

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

Объекты – это абстракция данных в Python. Все данные в программе Python представлены объектами или отношениями между объектами. (В некотором смысле, и в соответствии с моделью фон Неймана «компьютера с хранимой программой», код также представлен объектами.)

Каждый объект имеет идентичность, тип и значение. Идентичность объекта никогда не меняется после создания; её можно рассматривать как адрес объекта в памяти. Оператор 'is' сравнивает идентичность двух объектов; функция id() возвращает целое число, представляющее его идентичность (в текущей реализации – его адрес). Тип объекта также неизменяем. 1 Тип объекта определяет операции, которые он поддерживает (например, «есть ли у него длина?»), а также задаёт возможные значения для объектов этого типа. Функция type() возвращает тип объекта (который сам является объектом). Значение некоторых объектов может изменяться. Объекты, значение которых может меняться, называются изменяемыми; объекты, значение которых не может измениться после создания, называются неизменяемыми. (Значение неизменяемого контейнера, содержащего ссылку на изменяемый объект, может измениться при изменении значения последнего; однако контейнер всё равно считается неизменяемым, поскольку набор объектов, которые он содержит, изменить нельзя. Таким образом, неизменяемость не тождественна неизменяемости значения – это более тонкое понятие.) Изменяемость объекта определяется его типом; например, числа, строки и кортежи неизменяемы, а словари и списки – изменяемы.

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

Особенность реализации CPython: В CPython в настоящее время используется схема подсчёта ссылок с (опциональным) отложенным обнаружением циклически связанного мусора. Она собирает большинство объектов, как только они становятся недостижимыми, но не гарантирует сборку мусора, содержащего циклические ссылки. См. документацию модуля gc для получения информации об управлении сборкой циклического мусора. Другие реализации работают иначе, и CPython может измениться. Не полагайтесь на немедленную финализацию объектов, когда они становятся недостижимыми (например, всегда закрывайте файлы).

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

Некоторые объекты содержат ссылки на «внешние» ресурсы, такие как открытые файлы или окна. Подразумевается, что эти ресурсы освобождаются при сборке мусора, но поскольку сборка мусора не гарантируется, такие объекты также предоставляют явный способ освобождения внешнего ресурса, обычно метод close(). Программам настоятельно рекомендуется явно закрывать такие объекты. Инструкция 'tryfinally' предоставляет удобный способ сделать это.

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

Типы влияют почти на все аспекты поведения объектов. Даже важность идентичности объекта в некотором смысле затрагивается: для неизменяемых типов операции, вычисляющие новые значения, могут фактически возвращать ссылку на любой существующий объект с тем же типом и значением, в то время как для изменяемых объектов это не допускается. Например, после a = 1; b = 1, a и b могут ссылаться или не ссылаться на один и тот же объект со значением единицы, в зависимости от реализации, но после c = []; d = [], c и d гарантированно ссылаются на два разных, уникальных, только что созданных пустых списка. (Обратите внимание, что c = d = [] присваивает один и тот же объект как c, так и d.)

3.2. Стандартная иерархия типовThe standard type hierarchy

Ниже приведён список типов, встроенных в Python. Модули расширения (написанные на C, Java или других языках, в зависимости от реализации) могут определять дополнительные типы. Будущие версии Python могут добавлять типы в иерархию типов (например, рациональные числа, эффективно хранимые массивы целых чисел и т. д.).

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

None

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

NotImplemented

Этот тип имеет единственное значение. Существует только один объект с этим значением. Доступ к нему осуществляется через встроенное имя NotImplemented. Числовые методы и методы расширенного сравнения могут возвращать это значение, если они не реализуют операцию для переданных операндов. (Интерпретатор затем попробует отражённую операцию или какой-либо другой запасной вариант, в зависимости от оператора.) Его истинностное значение – истина.

Ellipsis

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

numbers.Number

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

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

numbers.Integral

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

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

Обычные целые числа

Эти числа представляют значения в диапазоне от -2147483648 до 2147483647. (Диапазон может быть больше на машинах с большим естественным размером слова, но не меньше.) Если результат операции выходит за этот диапазон, он обычно возвращается как длинное целое (в некоторых случаях вместо этого возбуждается исключение OverflowError). Для целей сдвиговых и битовых операций предполагается, что целые числа имеют двоичное представление в дополнительном коде с использованием 32 или более битов, при этом все биты доступны пользователю (то есть все 4294967296 различных комбинаций битов соответствуют разным значениям).

Длинные целые числа

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

Булевы значения

Они представляют истинностные значения False и True. Два объекта, представляющие значения False и True, являются единственными булевыми объектами. Булев тип является подтипом обычных целых чисел, и булевы значения ведут себя как значения 0 и 1 соответственно почти во всех контекстах, за исключением того, что при преобразовании в строку возвращаются строки "False" или "True" соответственно.

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

numbers.Real (float)

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

numbers.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.

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

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

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

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

Строки

Элементами строки являются символы. Отдельного типа для символов нет; символ представляется строкой из одного элемента. Символы представляют (как минимум) 8-битные байты. Встроенные функции chr() и ord() преобразуют символы в неотрицательные целые числа, представляющие значения байтов, и обратно. Байты со значениями 0–127 обычно представляют соответствующие ASCII-значения, но интерпретация значений зависит от программы. Строковый тип данных также используется для представления массивов байтов, например для хранения данных, прочитанных из файла.

(В системах, где национальный набор символов не является ASCII, строки могут использовать EBCDIC для внутреннего представления, при условии что функции chr() и ord() реализуют отображение между ASCII и EBCDIC, а сравнение строк сохраняет порядок ASCII. Или, возможно, кто-то предложит лучшее правило?)

Unicode

Элементами объекта Unicode являются кодовые единицы Unicode. Кодовая единица Unicode представляется объектом Unicode из одного элемента и может содержать 16-битное или 32-битное значение, представляющее порядковый номер Unicode (максимальное значение порядкового номера задаётся в sys.maxunicode и зависит от того, как Python скомпилирован). В объекте Unicode могут присутствовать суррогатные пары, и они будут сообщаться как два отдельных элемента. Встроенные функции unichr() и ord() преобразуют кодовые единицы в неотрицательные целые числа, представляющие порядковые номера Unicode, определённые в стандарте Unicode 3.0, и обратно. Преобразование в другие кодировки и из них возможно через метод Unicode encode() и встроенную функцию unicode().

Кортежи

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

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

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

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

Списки

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

Байтовые массивы

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

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

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

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

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

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

Множества

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

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

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

Отображения

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

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

Словари

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

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

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

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

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

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

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

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

Атрибут

Значение

__doc__ func_doc

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

Доступно для записи

__name__ func_name

Имя функции

Доступно для записи

__module__

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

Доступно для записи

__defaults__ func_defaults

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

Доступно для записи

__code__ func_code

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

Доступно для записи

__globals__ func_globals

Ссылка на словарь, содержащий глобальные переменные функции – глобальное пространство имён модуля, в котором функция была определена.

Только для чтения

__dict__ func_dict

Пространство имён, поддерживающее произвольные атрибуты функции.

Доступно для записи

__closure__ func_closure

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

Только для чтения

Большинство атрибутов, помеченных как «Доступно для записи», проверяют тип присваиваемого значения.

Изменено в версии 2.4: func_name теперь доступен для записи.

Изменено в версии 2.6: Атрибуты с двойным подчёркиванием __closure__, __code__, __defaults__ и __globals__ были введены как псевдонимы для соответствующих атрибутов func_* для обеспечения прямой совместимости с Python 3.

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

Дополнительную информацию об определении функции можно получить из её объекта code; см. описание внутренних типов ниже.

Пользовательские методы

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

Специальные атрибуты только для чтения: im_self – объект-экземпляр класса, im_func – объект-функция; im_class – класс объекта im_self для связанных методов или класс, запросивший метод, для несвязанных методов; __doc__ – документация метода (то же, что im_func.__doc__); __name__ – имя метода (то же, что im_func.__name__); __module__ – имя модуля, в котором определён метод, или None, если недоступно.

Изменено в версии 2.2: im_self ранее ссылался на класс, который определил метод.

Изменено в версии 2.6: Для совместимости с Python 3 вперёд, im_func также доступен как __func__, а im_self как __self__.

Методы также поддерживают доступ (но не установку) произвольных атрибутов функции на базовом объекте функции.

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

Когда объект пользовательского метода создаётся путём извлечения объекта пользовательской функции из класса, его атрибут im_self равен None, и такой метод называется несвязанным. Когда он создаётся путём извлечения объекта пользовательской функции из класса через один из его экземпляров, его атрибут im_self равен этому экземпляру, и метод называется связанным. В обоих случаях атрибут im_class нового метода – это класс, из которого производится извлечение, а его атрибут im_func – исходный объект функции.

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

Когда объект пользовательского метода создаётся путём извлечения объекта метода класса из класса или экземпляра, его атрибут im_self – это сам класс, а его атрибут im_func – объект функции, лежащий в основе метода класса.

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

Когда вызывается связанный объект пользовательского метода, вызывается базовая функция (im_func), при этом экземпляр класса (im_self) вставляется перед списком аргументов. Например, если C – класс, содержащий определение функции f(), а x – экземпляр C, то вызов x.f(1) эквивалентен вызову C.f(x, 1).

Когда объект пользовательского метода получен из объекта метода класса, «экземпляр класса», хранящийся в im_self, будет на самом деле самим классом, так что вызов x.f(1) или C.f(1) эквивалентен вызову f(C,1), где f – базовая функция.

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

Функции-генераторы

Функция или метод, использующие оператор yield (см. раздел Оператор yield), называются функцией-генератором. Такая функция при вызове всегда возвращает объект-итератор, который можно использовать для выполнения тела функции: вызов метода next() итератора заставляет функцию выполняться до тех пор, пока она не предоставит значение с помощью оператора yield. Когда функция выполняет оператор return или завершается естественным образом, возникает исключение StopIteration, и итератор достигает конца набора возвращаемых значений.

Встроенные функции

Объект встроенной функции – это обёртка вокруг функции на C. Примерами встроенных функций являются len() и math.sin() (math – стандартный встроенный модуль). Количество и тип аргументов определяются функцией на C. Специальные атрибуты только для чтения: __doc__ – строка документации функции или None, если недоступно; __name__ – имя функции; __self__ установлено в None (но см. следующий пункт); __module__ – имя модуля, в котором функция была определена, или None, если недоступно.

Встроенные методы

Это, по сути, другая форма встроенной функции, на этот раз содержащая объект, передаваемый функции на C как неявный дополнительный аргумент. Примером встроенного метода является alist.append(), если предположить, что alist – это объект списка. В этом случае специальный атрибут только для чтения __self__ устанавливается на объект, обозначенный alist.

Типы классов

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

Классические классы

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

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

Экземпляры классов описаны ниже. Экземпляры классов вызываемы только в том случае, если класс имеет метод __call__(); x(arguments) – это сокращение для x.__call__(arguments).

Модули

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

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

Специальный атрибут только для чтения: __dict__ – это пространство имён модуля в виде объекта словаря.

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

Предопределённые (доступные для записи) атрибуты: __name__ – имя модуля; __doc__ – строка документации модуля или None, если она недоступна; __file__ – путь к файлу, из которого был загружен модуль, если он был загружен из файла. Атрибут __file__ отсутствует для модулей C, статически слинкованных с интерпретатором; для модулей расширения, динамически загружаемых из разделяемой библиотеки, это путь к файлу разделяемой библиотеки.

Классы

Как типы классов (классы нового стиля), так и объекты классов (классы старого стиля/классические) обычно создаются определениями классов (см. раздел Определения классов). Класс имеет пространство имён, реализованное в виде словаря. Обращения к атрибутам класса преобразуются в поиск по этому словарю, например, C.x преобразуется в C.__dict__["x"] (хотя для классов нового стиля в частности существует ряд перехватчиков, позволяющих другие способы поиска атрибутов). Если имя атрибута не найдено там, поиск атрибута продолжается в базовых классах. Для классов старого стиля поиск выполняется в глубину, слева направо в порядке появления в списке базовых классов. Классы нового стиля используют более сложный порядок разрешения методов C3, который корректно работает даже при наличии «ромбовидных» структур наследования, где существует несколько путей наследования, ведущих к общему предку. Дополнительные сведения о C3 MRO, используемом классами нового стиля, можно найти в документации, сопровождающей выпуск 2.3, по адресу https://www.python.org/download/releases/2.3/mro/.

Когда обращение к атрибуту класса (для класса C, например) возвращает объект пользовательской функции или несвязанный объект пользовательского метода, чей связанный класс является C или одним из его базовых классов, он преобразуется в несвязанный объект пользовательского метода, чей атрибут im_class равен C. Когда возвращается объект метода класса, он преобразуется в связанный объект пользовательского метода, чей атрибут im_self равен C. Когда возвращается объект статического метода, он преобразуется в объект, обёрнутый объектом статического метода. См. раздел Реализация дескрипторов для другого способа, которым атрибуты, извлекаемые из класса, могут отличаться от тех, что фактически содержатся в его __dict__ (обратите внимание, что только классы нового стиля поддерживают дескрипторы).

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

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

Специальные атрибуты: __name__ – имя класса; __module__ – имя модуля, в котором определён класс; __dict__ – словарь, содержащий пространство имён класса; __bases__ – кортеж (возможно, пустой или из одного элемента), содержащий базовые классы в порядке их появления в списке базовых классов; __doc__ – строка документации класса или None, если она не определена.

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

Экземпляр класса создаётся вызовом объекта класса (см. выше). Экземпляр класса имеет пространство имён, реализованное в виде словаря, который является первым местом поиска атрибутов. Если атрибут не найден там и класс экземпляра имеет атрибут с таким именем, поиск продолжается среди атрибутов класса. Если найден атрибут класса, являющийся объектом пользовательской функции или несвязанным объектом пользовательского метода, чей связанный класс является классом (назовём его C) экземпляра, для которого было инициировано обращение к атрибуту, или одним из его базовых классов, он преобразуется в связанный объект пользовательского метода, чей атрибут im_class равен C и чей атрибут im_self равен экземпляру. Объекты статических методов и методов классов также преобразуются, как если бы они были извлечены из класса C; см. выше раздел «Классы». См. раздел Реализация дескрипторов для другого способа, которым атрибуты класса, извлекаемые через его экземпляры, могут отличаться от объектов, фактически хранящихся в __dict__ класса. Если атрибут класса не найден и у класса объекта есть метод __getattr__(), он вызывается для удовлетворения поиска.

Присваивания и удаления атрибутов обновляют словарь экземпляра, но никогда не словарь класса. Если у класса есть метод __setattr__() или __delattr__(), он вызывается вместо прямого обновления словаря экземпляра.

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

Специальные атрибуты: __dict__ – словарь атрибутов; __class__ – класс экземпляра.

Файлы

Объект файла представляет открытый файл. Объекты файлов создаются встроенной функцией open(), а также функциями os.popen(), os.fdopen() и методом makefile() объектов сокетов (и, возможно, другими функциями или методами, предоставляемыми модулями расширения). Объекты sys.stdin, sys.stdout и sys.stderr инициализируются как объекты файлов, соответствующие стандартным потокам ввода, вывода и ошибок интерпретатора. См. Объекты файлов для полной документации по объектам файлов.

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

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

Объекты кода

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

Специальные атрибуты только для чтения: co_name – имя функции; co_argcount – количество позиционных аргументов (включая аргументы со значениями по умолчанию); 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_restricted – флаг, указывающий, выполняется ли функция в ограниченном режиме выполнения; f_lasti – точная инструкция (это индекс в строке байт-кода объекта кода).

Специальные атрибуты, доступные для записи: f_trace, если не None, – функция, вызываемая в начале каждой строки исходного кода (используется отладчиком); f_exc_type, f_exc_value, f_exc_traceback представляют последнее исключение, возникшее в родительском кадре, если в текущем кадре когда-либо возникало другое исключение (во всех остальных случаях они равны None); f_lineno – текущий номер строки кадра – запись в этот атрибут из трассировочной функции переходит на заданную строку (только для самого нижнего кадра). Отладчик может реализовать команду Jump (также Set Next Statement), записывая в f_lineno.

Объекты трассировки стека

Объекты трассировки представляют стек вызовов исключения. Объект трассировки создаётся при возникновении исключения. Когда поиск обработчика исключения разворачивает стек выполнения, на каждом разворачиваемом уровне перед текущей трассировкой вставляется объект трассировки. Когда обработчик исключения входит, стек вызовов становится доступен программе. (См. раздел Оператор try.) Он доступен как sys.exc_traceback, а также как третий элемент кортежа, возвращаемого функцией sys.exc_info(). Последний является предпочтительным интерфейсом, поскольку он корректно работает, когда программа использует несколько потоков. Если в программе нет подходящего обработчика, трассировка стека выводится (в красивом формате) в стандартный поток ошибок; если интерпретатор работает в интерактивном режиме, она также становится доступна пользователю как sys.last_traceback.

Специальные атрибуты только для чтения: tb_next – следующий уровень в трассировке стека (направление к фрейму, где произошло исключение), или None, если следующего уровня нет; tb_frame указывает на фрейм выполнения текущего уровня; tb_lineno – номер строки, где произошло исключение; tb_lasti указывает точную инструкцию. Номер строки и последняя инструкция в трассировке могут отличаться от номера строки объекта фрейма, если исключение произошло в операторе try без подходящего предложения except или с предложением finally.

Объекты срезов

Объекты срезов используются для представления срезов при использовании расширенного синтаксиса срезов. Это срез с двумя двоеточиями, или несколько срезов или многоточий, разделённых запятыми, например, a[i:j:step], a[i:j, k:l] или a[..., i:j]. Они также создаются встроенной функцией slice().

Специальные атрибуты только для чтения: start – нижняя граница; stop – верхняя граница; step – шаг (значение); каждый равен None, если опущен. Эти атрибуты могут иметь любой тип.

Объекты slice поддерживают один метод:

slice.indices(self, length)

Этот метод принимает один целочисленный аргумент length и вычисляет информацию о расширенном срезе, который объект среза описывал бы, если бы был применён к последовательности из length элементов. Он возвращает кортеж из трёх целых чисел: соответственно это индексы start и stop, а также step или длина шага среза. Отсутствующие или выходящие за границы индексы обрабатываются так же, как и в обычных срезах.

Новое в версии 2.3.

Объекты статических методов

Объекты статических методов предоставляют способ обойти преобразование объектов-функций в объекты-методы, описанное выше. Объект статического метода – это обёртка вокруг любого другого объекта, обычно определённого пользователем объекта-метода. Когда объект статического метода извлекается из класса или экземпляра класса, фактически возвращается обёрнутый объект, который не подвергается дальнейшим преобразованиям. Сами объекты статических методов не являются вызываемыми, хотя объекты, которые они оборачивают, обычно вызываемы. Объекты статических методов создаются встроенным конструктором staticmethod().

Объекты методов классов

Объект метода класса, как и объект статического метода, является обёрткой вокруг другого объекта, изменяющей способ получения этого объекта из классов и экземпляров классов. Поведение объектов методов класса при таком получении описано выше, в разделе «Пользовательские методы». Объекты методов классов создаются встроенным конструктором classmethod().

3.3. Классы нового стиля и классические классыNew-style and classic classes

Классы и экземпляры бывают двух видов: старого стиля (или классические) и нового стиля.

До Python 2.1 концепция class не была связана с концепцией type, и единственным доступным видом были классы старого стиля. Для класса старого стиля оператор x.__class__ возвращает класс объекта x, но type(x) всегда равно <type 'instance'>. Это отражает тот факт, что все экземпляры старого стиля, независимо от их класса, реализованы с помощью одного встроенного типа, называемого instance.

Классы нового стиля были введены в Python 2.2, чтобы объединить понятия class и type. Класс нового стиля – это просто определяемый пользователем тип, не более и не менее. Если x – экземпляр класса нового стиля, то type(x) обычно совпадает с x.__class__ (хотя это не гарантируется – экземпляр класса нового стиля может переопределять значение, возвращаемое для x.__class__).

Основная причина введения классов нового стиля – предоставление единой объектной модели с полной метамоделью. У этого есть и ряд практических преимуществ, например, возможность наследовать большинство встроенных типов или введение «дескрипторов», которые позволяют создавать вычисляемые свойства.

По причинам обратной совместимости классы по умолчанию остаются старого стиля. Классы нового стиля создаются указанием другого класса нового стиля (т.е. типа) в качестве родительского или «верхнего типа» object, если другой родитель не нужен. Поведение классов нового стиля отличается от поведения классов старого стиля по ряду важных деталей помимо того, что возвращает type(). Некоторые из этих изменений являются фундаментальными для новой объектной модели, например, способ вызова специальных методов. Другие – это «исправления», которые раньше нельзя было реализовать из соображений совместимости, например, порядок разрешения методов при множественном наследовании.

Хотя данное руководство стремится дать всестороннее описание механики классов Python, в некоторых областях, касающихся классов нового стиля, оно может быть неполным. Дополнительные сведения см. на странице https://www.python.org/doc/newstyle/.

Классы старого стиля удалены в Python 3, остались только классы нового стиля.

3.4. Специальные имена методовSpecial method names

Класс может реализовать определённые операции, вызываемые специальным синтаксисом (например, арифметические операции или индексацию и срезы), определив методы со специальными именами. Это подход Python к перегрузке операторов, позволяющий классам определять собственное поведение для языковых операторов. Например, если класс определяет метод с именем __getitem__(), а x – экземпляр этого класса, то x[i] примерно эквивалентно x.__getitem__(i) для классов старого стиля и type(x).__getitem__(x, i) для классов нового стиля. Если не указано иное, при попытке выполнить операцию, для которой не определён подходящий метод, возникает исключение (обычно AttributeError или TypeError).

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

3.4.1. Базовая настройкаBasic customization

object.__new__(cls[, ...])

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

Обычные реализации создают новый экземпляр класса, вызывая метод __new__() суперкласса с помощью super(currentclass, cls).__new__(cls[, ...]) с соответствующими аргументами, а затем изменяют созданный экземпляр по необходимости перед возвратом.

Если __new__() возвращает экземпляр cls, то метод __init__() нового экземпляра будет вызван как __init__(self[, ...]), где self – новый экземпляр, а остальные аргументы те же, что были переданы __new__().

Если __new__() не возвращает экземпляр cls, то метод __init__() нового экземпляра вызываться не будет.

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

object.__init__(self[, ...])

Вызывается после создания экземпляра (с помощью __new__()), но до того, как он будет возвращён вызывающему коду. Аргументы – это те, что были переданы выражению конструктора класса. Если базовый класс имеет метод __init__(), то метод __init__() производного класса (если он есть) должен явно вызвать его, чтобы обеспечить правильную инициализацию базовой части экземпляра; например: BaseClass.__init__(self, [args...]).

Поскольку __new__() и __init__() работают совместно при создании объектов (__new__() создаёт объект, а __init__() настраивает его), __init__() не должна возвращать значение, отличное от None; иначе во время выполнения будет возбуждено TypeError.

object.__del__(self)

Вызывается, когда экземпляр собирается быть уничтоженным. Это также называется деструктором. Если базовый класс имеет метод __del__(), то метод __del__() производного класса (если он есть) должен явно вызвать его, чтобы гарантировать корректное удаление части базового класса экземпляра. Обратите внимание, что метод __del__() может (хотя это не рекомендуется!) отложить уничтожение экземпляра, создав новую ссылку на него. Затем он может быть вызван позже, когда эта новая ссылка будет удалена. Нет гарантии, что методы __del__() будут вызваны для объектов, которые всё ещё существуют при завершении интерпретатора.

Примечание

del x не вызывает напрямую x.__del__() – первое уменьшает счётчик ссылок на x на единицу, а второе вызывается только когда счётчик ссылок x достигает нуля. Некоторые распространённые ситуации, которые могут помешать счётчику ссылок объекта достичь нуля, включают: циклические ссылки между объектами (например, двусвязный список или древовидная структура с указателями на родительский и дочерние элементы); ссылку на объект в стековом кадре функции, перехватившей исключение (сохранённая в sys.exc_traceback трассировка держит стековый кадр живым); или ссылку на объект в стековом кадре, возбудившем необработанное исключение в интерактивном режиме (сохранённая в sys.last_traceback трассировка держит стековый кадр живым). Первая ситуация может быть исправлена только явным разрывом циклов; две последние – сохранением None в sys.exc_traceback или sys.last_traceback. Циклические ссылки-мусор обнаруживаются, когда включён детектор циклических ссылок (по умолчанию включён), но могут быть очищены только при отсутствии методов __del__() на уровне Python. Обратитесь к документации модуля gc за дополнительной информацией о том, как детектор циклических ссылок обрабатывает методы __del__(), особенно к описанию значения garbage.

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

Из-за непредсказуемых обстоятельств, при которых вызываются методы __del__(), исключения, возникающие во время их выполнения, игнорируются, а вместо этого в sys.stderr выводится предупреждение. Кроме того, когда __del__() вызывается в ответ на удаление модуля (например, при завершении программы), другие глобальные переменные, на которые ссылается метод __del__(), могут уже быть удалены или находиться в процессе удаления (например, механизм импорта завершает работу). По этой причине методы __del__() должны делать абсолютный минимум, необходимый для поддержания внешних инвариантов. Начиная с версии 1.5, Python гарантирует, что глобальные переменные, имена которых начинаются с одного символа подчёркивания, удаляются из своего модуля до того, как будут удалены другие глобальные переменные; если на такие глобальные переменные нет других ссылок, это может помочь гарантировать, что импортированные модули всё ещё доступны на момент вызова метода __del__().

См. также опцию командной строки -R.

object.__repr__(self)

Вызывается встроенной функцией repr() и при строковых преобразованиях (обратные кавычки) для получения «официального» строкового представления объекта. По возможности оно должно выглядеть как корректное выражение Python, которое можно использовать для воссоздания объекта с тем же значением (при подходящем окружении). Если это невозможно, следует вернуть строку вида <...some useful description...>. Возвращаемое значение должно быть строковым объектом. Если класс определяет __repr__(), но не __str__(), то __repr__() также используется, когда требуется «неформальное» строковое представление экземпляров этого класса.

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

object.__str__(self)

Вызывается встроенной функцией str() и оператором print для получения «неформального» строкового представления объекта. Отличается от __repr__() тем, что не обязано быть корректным выражением Python: вместо этого может использоваться более удобное или краткое представление. Возвращаемое значение должно быть строковым объектом.

object.__lt__(self, other)
object.__le__(self, other)
object.__eq__(self, other)
object.__ne__(self, other)
object.__gt__(self, other)
object.__ge__(self, other)

Новое в версии 2.1.

Это так называемые методы «богатого сравнения»; они вызываются для операторов сравнения в приоритете над __cmp__() ниже. Соответствие между символами операторов и именами методов следующее: x<y вызывает x.__lt__(y), x<=y вызывает x.__le__(y), x==y вызывает x.__eq__(y), x!=y и x<>y вызывают x.__ne__(y), x>y вызывает x.__gt__(y), а x>=y вызывает x.__ge__(y).

Метод расширенного сравнения может вернуть синглтон NotImplemented, если он не реализует операцию для данной пары аргументов. По соглашению, при успешном сравнении возвращаются False и True. Однако эти методы могут возвращать любое значение, поэтому если оператор сравнения используется в логическом контексте (например, в условии оператора if), Python вызовет bool() для этого значения, чтобы определить, истинно оно или ложно.

Между операторами сравнения нет подразумеваемых отношений. Истинность x==y не означает, что x!=y ложно. Соответственно, определяя __eq__(), следует также определить __ne__(), чтобы операторы вели себя как ожидается. См. параграф о __hash__() для важных замечаний по созданию хэшируемых объектов, поддерживающих пользовательские операции сравнения и пригодных для использования в качестве ключей словаря.

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

Аргументы методов расширенного сравнения никогда не приводятся.

Чтобы автоматически генерировать операции упорядочивания из одной базовой операции, см. functools.total_ordering().

object.__cmp__(self, other)

Вызывается операциями сравнения, если не определён метод богатого сравнения (см. выше). Должен возвращать отрицательное целое число, если self < other, ноль, если self == other, положительное целое, если self > other. Если не определена ни __cmp__(), ни __eq__(), ни __ne__(), экземпляры классов сравниваются по идентичности объектов («адресу»). См. также описание __hash__() для важных замечаний по созданию хэшируемых объектов, поддерживающих пользовательские операции сравнения и пригодных для использования в качестве ключей словаря. (Примечание: ограничение, что исключения не распространяются через __cmp__(), снято начиная с Python 1.5.)

object.__rcmp__(self, other)

Изменено в версии 2.1: Больше не поддерживается.

object.__hash__(self)

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

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

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

Пользовательские классы по умолчанию имеют методы __cmp__() и __hash__(); с ними все объекты считаются неравными (кроме сравнения с самим собой), а x.__hash__() возвращает результат, полученный из id(x).

Классы, которые наследуют метод __hash__() от родительского класса, но изменяют смысл __cmp__() или __eq__() так, что возвращаемое хеш-значение больше не подходит (например, переходя на понятие равенства на основе значения вместо равенства на основе идентичности по умолчанию), могут явно пометить себя как нехешируемые, установив __hash__ = None в определении класса. Это означает, что не только экземпляры класса будут вызывать соответствующее TypeError при попытке программы получить их хеш-значение, но также они будут правильно идентифицироваться как нехешируемые при проверке isinstance(obj, collections.Hashable) (в отличие от классов, которые определяют собственный __hash__(), чтобы явно вызывать TypeError).

Изменено в версии 2.5: __hash__() теперь может также возвращать объект длинного целого; 32-битное целое затем получается из хеша этого объекта.

Изменено в версии 2.6: __hash__ теперь может быть установлено в None, чтобы явно помечать экземпляры класса как нехешируемые.

object.__nonzero__(self)

Вызывается для реализации проверки истинности и встроенной операции bool(); должна возвращать False или True, или их целочисленные эквиваленты 0 или 1. Если этот метод не определён, вызывается __len__() (если он определён), и объект считается истинным, если его результат ненулевой. Если класс не определяет ни __len__(), ни __nonzero__(), все его экземпляры считаются истинными.

object.__unicode__(self)

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

3.4.2. Настройка доступа к атрибутамCustomizing attribute access

Следующие методы могут быть определены для настройки смысла доступа к атрибутам (чтения, присваивания или удаления x.name) для экземпляров классов.

object.__getattr__(self, name)

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

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

object.__setattr__(self, name, value)

Вызывается при попытке присвоения атрибута. Вызывается вместо обычного механизма (т.е. сохранения значения в словаре экземпляра). name – имя атрибута, value – присваиваемое значение.

Если __setattr__() хочет присвоить значение атрибуту экземпляра, он не должен просто выполнять self.name = value – это приведёт к рекурсивному вызову самого себя. Вместо этого он должен вставить значение в словарь атрибутов экземпляра, например, self.__dict__[name] = value. Для классов нового стиля, вместо обращения к словарю экземпляра, он должен вызвать метод базового класса с тем же именем, например, object.__setattr__(self, name, value).

object.__delattr__(self, name)

Как __setattr__(), но для удаления атрибутов вместо присваивания. Этот метод следует реализовывать, только если del obj.name имеет смысл для объекта.

3.4.2.1. Дополнительный доступ к атрибутам для классов нового стиляMore attribute access for new-style classes

Следующие методы применимы только к классам нового стиля.

object.__getattribute__(self, name)

Вызывается безусловно для реализации доступа к атрибутам экземпляров класса. Если класс также определяет __getattr__(), последний не будет вызван, пока __getattribute__() либо не вызовет его явно, либо не вызовет AttributeError. Этот метод должен возвращать (вычисленное) значение атрибута или вызывать исключение AttributeError. Чтобы избежать бесконечной рекурсии в этом методе, его реализация всегда должна вызывать метод базового класса с тем же именем для доступа к любым необходимым атрибутам, например, object.__getattribute__(self, name).

Примечание

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

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

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

object.__get__(self, instance, owner)

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

object.__set__(self, instance, value)

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

object.__delete__(self, instance)

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

3.4.2.3. Вызов дескрипторовInvoking Descriptors

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

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

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

Отправная точка для вызова дескриптора – привязка, a.x. Способ сборки аргументов зависит от a:

Прямой вызов

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

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

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

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

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

Привязка через super

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

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

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

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

3.4.2.4. __slots__

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

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

__slots__

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

Новое в версии 2.2.

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

  • При наследовании от класса без __slots__ атрибут __dict__ этого класса всегда будет доступен, поэтому определение __slots__ в подклассе не имеет смысла.

  • Без переменной __dict__ экземплярам нельзя присваивать новые переменные, не перечисленные в определении __slots__. Попытка присвоить значение не перечисленному имени переменной вызывает AttributeError. Если требуется динамическое присваивание новых переменных, добавьте '__dict__' в последовательность строк в объявлении __slots__.

    Изменено в версии 2.3: Ранее добавление '__dict__' в объявление __slots__ не позволяло присваивать новые атрибуты, не указанные явно в последовательности имён переменных экземпляра.

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

    Изменено в версии 2.3: Ранее добавление '__weakref__' в объявление __slots__ не включало поддержку слабых ссылок.

  • __slots__ реализуются на уровне класса путём создания дескрипторов (Реализация дескрипторов) для каждого имени переменной. В результате атрибуты класса нельзя использовать для установки значений по умолчанию для переменных экземпляра, определённых __slots__; в противном случае атрибут класса перезаписал бы присваивание дескриптора.

  • Действие объявления __slots__ ограничено классом, в котором оно определено. В результате подклассы будут иметь __dict__, если только они также не определят __slots__ (который должен содержать только имена дополнительных слотов).

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

  • Непустой __slots__ не работает для классов, производных от встроенных типов «переменной длины», таких как long, str и tuple.

  • Любому итерируемому объекту, не являющемуся строкой, может быть присвоено __slots__. Также могут использоваться отображения; однако в будущем значениям, соответствующим каждому ключу, может быть присвоен особый смысл.

  • Присваивание __class__ работает, только если оба класса имеют одинаковые __slots__.

    Изменено в версии 2.6: Ранее присваивание __class__ вызывало ошибку, если новый или старый класс содержал __slots__.

3.4.3. Настройка создания классовCustomizing class creation

По умолчанию классы нового стиля создаются с помощью type(). Определение класса читается в отдельное пространство имён, а значение имени класса связывается с результатом type(name, bases, dict).

Когда читается определение класса, если определён __metaclass__, то вместо type() будет вызван вызываемый объект, присвоенный ему. Это позволяет писать классы или функции, которые отслеживают или изменяют процесс создания класса:

  • Изменение словаря класса до его создания.

  • Возврат экземпляра другого класса – по сути выполнение роли фабричной функции.

Эти шаги должны быть выполнены в методе __new__() метакласса – type.__new__() затем можно вызвать из этого метода для создания класса с другими свойствами. В этом примере в словарь класса добавляется новый элемент перед созданием класса:

class metacls(type):
    def __new__(mcs, name, bases, dict):
        dict['foo'] = 'metacls was here'
        return type.__new__(mcs, name, bases, dict)

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

__metaclass__

Эта переменная может быть любым вызываемым объектом, принимающим аргументы для name, bases и dict. При создании класса этот вызываемый объект используется вместо встроенного type().

Новое в версии 2.2.

Подходящий метакласс определяется следующими правилами приоритета:

  • Если dict['__metaclass__'] существует, он используется.

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

  • В противном случае, если существует глобальная переменная с именем __metaclass__, она используется.

  • В противном случае используется метакласс старого стиля (types.ClassType).

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

3.4.4. Customizing instance and subclass checks

Новое в версии 2.6.

Следующие методы используются для переопределения поведения по умолчанию встроенных функций isinstance() и issubclass().

В частности, метакласс abc.ABCMeta реализует эти методы,\чтобы позволить добавлять абстрактные базовые классы (ABC) как «виртуальные базовые классы» к любому классу или типу (включая встроенные типы), в том числе к другим ABC.

class.__instancecheck__(self, instance)

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

class.__subclasscheck__(self, subclass)

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

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

См. также

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

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

3.4.5. Эмуляция вызываемых объектовEmulating callable objects

object.__call__(self[, args...])

Вызывается, когда экземпляр «вызывается» как функция; если этот метод определён, x(arg1, arg2, ...) является сокращённой формой для x.__call__(arg1, arg2, ...).

3.4.6. Эмуляция контейнерных типовEmulating container types

Могут быть определены следующие методы для реализации объектов-контейнеров. Контейнеры обычно являются последовательностями (такими как списки или кортежи) или отображениями (например, словари), но могут представлять и другие контейнеры. Первый набор методов используется для эмуляции как последовательности, так и отображения; разница в том, что для последовательности допустимыми ключами должны быть целые числа k, для которых 0 <= k < N, где N – длина последовательности, или объекты срезов, определяющие диапазон элементов. (Для обратной совместимости может быть также определён метод __getslice__() (см. ниже) для обработки простых, но не расширенных срезов.) Также рекомендуется, чтобы отображения предоставляли методы keys(), values(), items(), has_key(), get(), clear(), setdefault(), iterkeys(), itervalues(), iteritems(), pop(), popitem(), copy() и update(), ведущие себя аналогично соответствующим методам стандартных словарей Python. Модуль UserDict предоставляет класс DictMixin для создания этих методов на основе базового набора __getitem__(), __setitem__(), __delitem__() и keys(). Изменяемые последовательности должны предоставлять методы append(), count(), index(), extend(), insert(), pop(), remove(), reverse() и sort(), как стандартные объекты списков Python. Наконец, типы последовательностей должны реализовывать сложение (то есть конкатенацию) и умножение (то есть повторение) путём определения методов __add__(), __radd__(), __iadd__(), __mul__(), __rmul__() и __imul__(), описанных ниже; они не должны определять __coerce__() или другие числовые операторы. Рекомендуется, чтобы и отображения, и последовательности реализовывали метод __contains__() для эффективного использования оператора in; для отображений in должен быть эквивалентен has_key(); для последовательностей он должен искать по значениям. Также рекомендуется, чтобы и отображения, и последовательности реализовывали метод __iter__() для эффективной итерации по контейнеру; для отображений __iter__() должно быть то же самое, что iterkeys(); для последовательностей он должен итерировать по значениям.

object.__len__(self)

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

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

object.__getitem__(self, key)

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

Примечание

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

object.__setitem__(self, key, value)

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

object.__delitem__(self, key)

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

object.__missing__(self, key)

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

object.__iter__(self)

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

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

object.__reversed__(self)

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

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

Новое в версии 2.6.

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

object.__contains__(self, item)

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

Для объектов, которые не определяют __contains__(), проверка вхождения сначала пытается выполнить итерацию через __iter__(), затем старый протокол итерации последовательностей через __getitem__(); см. этот раздел в справочнике по языку.

3.4.7. Дополнительные методы для эмуляции типов последовательностейAdditional methods for emulation of sequence types

Следующие необязательные методы можно определить для дальнейшей эмуляции объектов последовательностей. Неизменяемые последовательности должны определять максимум только __getslice__(); изменяемые последовательности могут определять все три метода.

object.__getslice__(self, i, j)

Устарело с версии 2.0: Поддержка объектов срезов в качестве параметров метода __getitem__(). (Однако встроенные типы в CPython по-прежнему реализуют __getslice__(). Поэтому при реализации срезов его необходимо переопределять в производных классах.)

Вызывается для реализации вычисления self[i:j]. Возвращаемый объект должен быть того же типа, что и self. Обратите внимание, что отсутствующие i или j в выражении среза заменяются на ноль или sys.maxsize соответственно. Если в срезе используются отрицательные индексы, к индексу добавляется длина последовательности. Если экземпляр не реализует метод __len__(), возбуждается AttributeError. Не гарантируется, что скорректированные таким образом индексы не останутся отрицательными. Индексы, превышающие длину последовательности, не изменяются. Если __getslice__() не найдено, вместо него создаётся объект среза и передаётся в __getitem__().

object.__setslice__(self, i, j, sequence)

Вызывается для реализации присваивания self[i:j]. Те же примечания для i и j, что и для __getslice__().

Этот метод устарел. Если __setslice__() не найден, или для расширенной срезки вида self[i:j:k], создаётся объект среза, который передаётся в __setitem__(), вместо вызова __setslice__().

object.__delslice__(self, i, j)

Вызывается для реализации удаления self[i:j]. Те же примечания для i и j, что и для __getslice__(). Этот метод устарел. Если __delslice__() не найден, или для расширенной срезки вида self[i:j:k], создаётся объект среза, который передаётся в __delitem__(), вместо вызова __delslice__().

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

Следующий пример показывает, как сделать программу или модуль совместимыми с более ранними версиями Python (предполагается, что методы __getitem__(), __setitem__() и __delitem__() поддерживают объекты срезов в качестве аргументов):

class MyClass:
    ...
    def __getitem__(self, index):
        ...
    def __setitem__(self, index, value):
        ...
    def __delitem__(self, index):
        ...

    if sys.version_info < (2, 0):
        # Они не будут определены, если версия не ниже 2.0 final

        def __getslice__(self, i, j):
            return self[max(0, i):max(0, j):]
        def __setslice__(self, i, j, seq):
            self[max(0, i):max(0, j):] = seq
        def __delslice__(self, i, j):
            del self[max(0, i):max(0, j):]
    ...

Обратите внимание на вызовы max(); они необходимы из-за обработки отрицательных индексов перед вызовом методов __*slice__(). Когда используются отрицательные индексы, методы __*item__() получают их в том виде, в каком они переданы, а методы __*slice__() получают «приготовленную» форму значений индексов. Для каждого отрицательного значения индекса к нему перед вызовом метода добавляется длина последовательности (что всё ещё может дать отрицательный индекс); это стандартная обработка отрицательных индексов встроенными типами последовательностей, и методы __*item__() тоже должны так делать. Однако, поскольку они уже должны это делать, отрицательные индексы не могут быть переданы напрямую; они должны быть ограничены границами последовательности перед передачей в методы __*item__(). Вызов max(0, i) удобно возвращает подходящее значение.

3.4.8. Эмуляция числовых типовEmulating numeric types

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

object.__add__(self, other)
object.__sub__(self, other)
object.__mul__(self, other)
object.__floordiv__(self, other)
object.__mod__(self, other)
object.__divmod__(self, other)
object.__pow__(self, other[, modulo])
object.__lshift__(self, other)
object.__rshift__(self, other)
object.__and__(self, other)
object.__xor__(self, other)
object.__or__(self, other)

Эти методы вызываются для реализации бинарных арифметических операций (+, -, *, //, %, divmod(), pow(), **, <<, >>, &, ^, |). Например, для вычисления выражения x + y, где x является экземпляром класса, у которого есть метод __add__(), вызывается x.__add__(y). Метод __divmod__() должен быть эквивалентен использованию __floordiv__() и __mod__(); он не должен быть связан с __truediv__() (описано ниже). Обратите внимание, что __pow__() должен быть определён так, чтобы принимать необязательный третий аргумент, если должна поддерживаться тернарная версия встроенной функции pow().

Если один из этих методов не поддерживает операцию с переданными аргументами, он должен вернуть NotImplemented.

object.__div__(self, other)
object.__truediv__(self, other)

Оператор деления (/) реализуется этими методами. Метод __truediv__() используется, когда действует __future__.division, в противном случае используется __div__(). Если определён только один из этих двух методов, объект не будет поддерживать деление в альтернативном контексте; вместо этого будет возбуждено TypeError.

object.__radd__(self, other)
object.__rsub__(self, other)
object.__rmul__(self, other)
object.__rdiv__(self, other)
object.__rtruediv__(self, other)
object.__rfloordiv__(self, other)
object.__rmod__(self, other)
object.__rdivmod__(self, other)
object.__rpow__(self, other)
object.__rlshift__(self, other)
object.__rrshift__(self, other)
object.__rand__(self, other)
object.__rxor__(self, other)
object.__ror__(self, other)

Эти методы вызываются для реализации бинарных арифметических операций (+, -, *, /, %, divmod(), pow(), **, <<, >>, &, ^, |) с отражёнными (переставленными) операндами. Эти функции вызываются только в том случае, если левый операнд не поддерживает соответствующую операцию и операнды относятся к разным типам. 2 Например, для вычисления выражения 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.__idiv__(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 += y, где x – экземпляр класса, имеющего метод __iadd__(), вызывается x.__iadd__(y). Если x – экземпляр класса, не определяющего метод __iadd__(), рассматриваются x.__add__(y) и y.__radd__(x), как и при вычислении x + y.

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

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

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

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

object.__oct__(self)
object.__hex__(self)

Вызывается для реализации встроенных функций oct() и hex(). Должен возвращать строковое значение.

object.__index__(self)

Вызывается для реализации operator.index(). Также вызывается, когда Python требуется целочисленный объект (например, при взятии среза). Должен возвращать целое число (int или long).

Новое в версии 2.5.

object.__coerce__(self, other)

Called to implement “mixed-mode” numeric arithmetic. Should either return a 2-tuple containing self and other converted to a common numeric type, or None if conversion is impossible. When the common type would be the type of other, it is sufficient to return None, since the interpreter will also ask the other object to attempt a coercion (but sometimes, if the implementation of the other type cannot be changed, it is useful to do the conversion to the other type here). A return value of NotImplemented is equivalent to returning None.

3.4.9. Правила приведенияCoercion rules

В этом разделе ранее документировались правила приведения. По мере развития языка правила приведения стало трудно точно документировать; документировать то, что делает одна версия конкретной реализации, нежелательно. Вместо этого приведены неформальные рекомендации по приведению. В Python 3 приведение поддерживаться не будет.

  • Если левый операнд оператора % является строкой или объектом Unicode, приведение не выполняется, и вместо него вызывается операция форматирования строки.

  • Больше не рекомендуется определять операцию приведения. При смешанном режиме для типов, не определяющих приведение, исходные аргументы передаются операции.

  • Классы нового стиля (производные от object) никогда не вызывают метод __coerce__() в ответ на бинарный оператор; единственный случай, когда вызывается __coerce__() – это когда вызывается встроенная функция coerce().

  • Для большинства целей и задач оператор, возвращающий NotImplemented, обрабатывается так же, как и вовсе не реализованный.

  • Ниже __op__() и __rop__() используются для обозначения общих имён методов, соответствующих оператору; __iop__() используется для соответствующего оператора на месте. Например, для оператора '+' __add__() и __radd__() используются для левого и правого вариантов бинарного оператора, а __iadd__() – для варианта на месте.

  • Для объектов x и y сначала пробуется x.__op__(y). Если он не реализован или возвращает NotImplemented, пробуется y.__rop__(x). Если он также не реализован или возвращает NotImplemented, возбуждается исключение TypeError. Но см. следующее исключение:

  • Исключение из предыдущего пункта: если левый операнд является экземпляром встроенного типа или класса нового стиля, а правый операнд является экземпляром прямого подкласса этого типа или класса и переопределяет метод __rop__() базового класса, то сначала пробуется метод __rop__() правого операнда до метода __op__() левого операнда.

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

  • Когда любой из типов операндов определяет приведение, это приведение вызывается до вызова метода __op__() или __rop__() этого типа, но не раньше. Если приведение возвращает объект другого типа для операнда, чьё приведение было вызвано, часть процесса повторяется с использованием нового объекта.

  • Когда используется оператор на месте (например, '+='), если левый операнд реализует __iop__(), он вызывается без какого-либо приведения. Когда операция возвращается к __op__() и/или __rop__(), применяются обычные правила приведения.

  • В x + y, если x является последовательностью, реализующей конкатенацию последовательностей, вызывается конкатенация последовательностей.

  • В x * y, если один операнд является последовательностью, реализующей повторение последовательности, а другой – целым числом (int или long), вызывается повторение последовательности.

  • Богатые сравнения (реализуемые методами __eq__() и так далее) никогда не используют приведение. Трёхстороннее сравнение (реализуемое __cmp__()) использует приведение на тех же условиях, что и другие бинарные операции.

  • В текущей реализации встроенные числовые типы int, long, float и complex не используют приведение. Все эти типы реализуют метод __coerce__() для использования встроенной функцией coerce().

    Изменено в версии 2.7: Тип complex больше не выполняет неявных вызовов метода __coerce__() для бинарных арифметических операций со смешанными типами.

3.4.10. Контекстные менеджеры оператора withWith Statement Context Managers

Новое в версии 2.5.

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

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

Для получения дополнительной информации о контекстных менеджерах см. Типы контекстных менеджеров.

object.__enter__(self)

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

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

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

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

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

См. также

PEP 343 – Оператор «with»

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

3.4.11. Поиск специальных методов для классов старого стиляSpecial method lookup for old-style classes

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

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

>>> class C:
...     pass
...
>>> c1 = C()
>>> c2 = C()
>>> c1.__len__ = lambda: 5
>>> c2.__len__ = lambda: 9
>>> len(c1)
5
>>> len(c2)
9

3.4.12. Поиск специальных методов для классов нового стиляSpecial method lookup for new-style classes

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

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

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

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

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

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

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

>>> class Meta(type):
...    def __getattribute__(*args):
...       print "Metaclass getattribute invoked"
...       return type.__getattribute__(*args)
...
>>> class C(object):
...     __metaclass__ = Meta
...     def __len__(self):
...         return 10
...     def __getattribute__(*args):
...         print "Class getattribute invoked"
...         return object.__getattribute__(*args)
...
>>> c = C()
>>> c.__len__()                 # Явный поиск через экземпляр
Class getattribute invoked
10
>>> type(c).__len__(c)          # Явный поиск через тип
Metaclass getattribute invoked
10
>>> len(c)                      # Неявный поиск
10

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

Сноски

1

It is possible in some cases to change an object’s type, under certain controlled conditions. It generally isn’t a good idea though, since it can lead to some very strange behaviour if it is handled incorrectly.

2

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