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

datamodel.md

1072 строк · 159.4 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/3.4/reference/datamodel.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 3. Модель данных89## 3.1. Объекты, значения и типы1011*Объекты* – это абстракция данных в Python. Все данные в программе Python представлены объектами или отношениями между объектами. (В некотором смысле, и в соответствии с моделью фон Неймана «компьютера с хранимой программой», код также представлен объектами.)1213Каждый объект имеет идентичность, тип и значение. *Идентичность* объекта никогда не меняется после его создания; её можно рассматривать как адрес объекта в памяти. Оператор ‘[`is`](https://python-all.ru/3.4/reference/expressions.html#is)‘ сравнивает идентичность двух объектов; функция [`id()`](https://python-all.ru/3.4/library/functions.html#id) возвращает целое число, представляющее его идентичность.1415**Особенность реализации CPython:** Для CPython `id(x)` – это адрес памяти, где хранится `x`.1617Тип объекта определяет операции, которые объект поддерживает (например, «есть ли у него длина?»), а также задаёт возможные значения для объектов этого типа. Функция [`type()`](https://python-all.ru/3.4/library/functions.html#type) возвращает тип объекта (который сам является объектом). Как и идентичность, *тип* объекта также неизменяем. [\[1\]](https://python-all.ru/3.4/reference/datamodel.html#id4)1819*Значение* некоторых объектов может изменяться. Объекты, значение которых может изменяться, называются *изменяемыми*; объекты, значение которых неизменно после создания, называются *неизменяемыми*. (Значение неизменяемого объекта-контейнера, содержащего ссылку на изменяемый объект, может измениться при изменении последнего; однако контейнер всё равно считается неизменяемым, потому что набор содержащихся в нём объектов изменить нельзя. Таким образом, неизменяемость не тождественна неизменности значения – это тоньше.) Изменяемость объекта определяется его типом; например, числа, строки и кортежи неизменяемы, а словари и списки изменяемы.2021Объекты никогда не уничтожаются явно; однако, когда они становятся недостижимыми, они могут быть собраны сборщиком мусора. Реализация может откладывать сборку мусора или вовсе её не выполнять – качество реализации определяет, как именно реализована сборка мусора, при условии, что не собираются объекты, которые всё ещё достижимы.2223**Особенность реализации CPython:** В CPython в настоящее время используется схема подсчёта ссылок с (опциональным) отложенным обнаружением циклически связанного мусора, которая собирает большинство объектов сразу после того, как они становятся недостижимыми, но не гарантирует сборку мусора, содержащего циклические ссылки. См. документацию модуля [`gc`](https://python-all.ru/3.4/library/gc.html#module-gc) для получения информации об управлении сборкой циклического мусора. Другие реализации ведут себя иначе, и CPython может измениться. Не полагайтесь на немедленную финализацию объектов, когда они становятся недостижимыми (поэтому всегда следует явно закрывать файлы).2425Обратите внимание, что использование средств трассировки или отладки реализации может удерживать объекты в памяти, которые в обычных условиях были бы собираемыми. Также обратите внимание, что перехват исключения с помощью оператора ‘[`try`](https://python-all.ru/3.4/reference/compound_stmts.html#try)...[`except`](https://python-all.ru/3.4/reference/compound_stmts.html#except)‘ может удерживать объекты в памяти.2627Некоторые объекты содержат ссылки на «внешние» ресурсы, такие как открытые файлы или окна. Подразумевается, что эти ресурсы освобождаются при сборке мусора объекта, но поскольку сборка мусора не гарантируется, такие объекты также предоставляют явный способ освобождения внешнего ресурса – обычно метод `close()`. Программам настоятельно рекомендуется явно закрывать такие объекты. Оператор ‘[`try`](https://python-all.ru/3.4/reference/compound_stmts.html#try)...[`finally`](https://python-all.ru/3.4/reference/compound_stmts.html#finally)‘ и оператор ‘[`with`](https://python-all.ru/3.4/reference/compound_stmts.html#with)‘ предоставляют удобные способы сделать это.2829Некоторые объекты содержат ссылки на другие объекты; они называются *контейнерами*. Примерами контейнеров являются кортежи, списки и словари. Ссылки являются частью значения контейнера. В большинстве случаев, когда мы говорим о значении контейнера, мы подразумеваем значения, а не идентификаторы содержащихся объектов; однако, когда мы говорим об изменяемости контейнера, подразумеваются только идентификаторы непосредственно содержащихся объектов. Таким образом, если неизменяемый контейнер (например, кортеж) содержит ссылку на изменяемый объект, его значение изменяется при изменении этого изменяемого объекта.3031Типы влияют практически на все аспекты поведения объектов. Даже значимость идентичности объекта в некотором смысле меняется: для неизменяемых типов операции, вычисляющие новые значения, могут фактически возвращать ссылку на любой существующий объект с тем же типом и значением, в то время как для изменяемых объектов это не допускается. Например, после `a = 1; b = 1`, `a` и `b` могут ссылаться или не ссылаться на один и тот же объект со значением 1 в зависимости от реализации, но после `c = []; d = []`, `c` и `d` гарантированно ссылаются на два разных, уникальных, только что созданных пустых списка. (Заметьте, что `c = d = []` присваивает один и тот же объект обоим `c` и `d`.)3233## 3.2. Стандартная иерархия типов3435Ниже приведён список типов, встроенных в Python. Модули расширения (написанные на C, Java или других языках в зависимости от реализации) могут определять дополнительные типы. Будущие версии Python могут добавлять типы в иерархию (например, рациональные числа, эффективно хранимые массивы целых чисел и т.д.), хотя такие дополнения чаще будут предоставляться через стандартную библиотеку.3637Некоторые описания типов ниже содержат абзац, перечисляющий «специальные атрибуты». Это атрибуты, обеспечивающие доступ к реализации и не предназначенные для общего использования. Их определение может измениться в будущем.3839**None**4041Этот тип имеет единственное значение. Существует единственный объект с этим значением. Доступ к этому объекту осуществляется через встроенное имя `None`. Он используется для обозначения отсутствия значения во многих ситуациях, например, возвращается из функций, которые ничего явно не возвращают. Его истинностное значение – ложь.4243**NotImplemented**4445Этот тип имеет единственное значение. Существует единственный объект с этим значением. Доступ к этому объекту осуществляется через встроенное имя `NotImplemented`. Числовые методы и методы расширенного сравнения должны возвращать это значение, если они не реализуют операцию для указанных операндов. (Интерпретатор затем попробует отражённую операцию или другой запасной вариант в зависимости от оператора.) Его истинностное значение – истина.4647См. [*Реализация арифметических операций*](https://python-all.ru/3.4/library/numbers.html#implementing-the-arithmetic-operations) для получения дополнительных сведений.4849**Ellipsis**5051Этот тип имеет единственное значение. Существует единственный объект с этим значением. Доступ к этому объекту осуществляется через литерал `...` или встроенное имя `Ellipsis`. Его истинностное значение – истина.5253**[`numbers.Number`](https://python-all.ru/3.4/library/numbers.html#numbers.Number)**5455Они создаются числовыми литералами и возвращаются в результате работы арифметических операторов и встроенных арифметических функций. Числовые объекты неизменяемы; после создания их значение никогда не меняется. Числа в Python, конечно, тесно связаны с математическими числами, но подвержены ограничениям числового представления в компьютерах.5657Python различает целые числа, числа с плавающей запятой и комплексные числа:5859**[`numbers.Integral`](https://python-all.ru/3.4/library/numbers.html#numbers.Integral)**6061Они представляют элементы из математического множества целых чисел (положительных и отрицательных).6263Существует два типа целых чисел:6465Целые числа ([`int`](https://python-all.ru/3.4/library/functions.html#int))6667> Они представляют числа в неограниченном диапазоне, ограниченном лишь доступной (виртуальной) памятью. Для операций сдвига и маскирования используется двоичное представление, а отрицательные числа представляются в варианте дополнительного кода, который создаёт иллюзию бесконечной строки знаковых битов, уходящей влево.6869**Булевы значения ([`bool`](https://python-all.ru/3.4/library/functions.html#bool))**7071Они представляют истинностные значения False и True. Два объекта, представляющие значения `False` и `True`, являются единственными булевыми объектами. Булев тип является подтипом целочисленного типа, и булевы значения ведут себя как значения 0 и 1 соответственно почти во всех контекстах, за исключением того, что при преобразовании в строку возвращаются строки `"False"` или `"True"` соответственно.7273Правила представления целых чисел призваны давать наиболее осмысленную интерпретацию операций сдвига и маскирования, в которых участвуют отрицательные целые числа.7475**[`numbers.Real`](https://python-all.ru/3.4/library/numbers.html#numbers.Real) ([`float`](https://python-all.ru/3.4/library/functions.html#float))**7677Эти числа представляют собой машинные числа с плавающей запятой двойной точности. Допустимый диапазон и обработка переполнения определяются нижележащей архитектурой машины (и реализацией на C или Java). Python не поддерживает числа с плавающей запятой одинарной точности; экономия процессора и памяти, которая обычно является причиной их использования, ничтожна по сравнению с накладными расходами на использование объектов в Python, поэтому нет смысла усложнять язык двумя видами чисел с плавающей запятой.7879**[`numbers.Complex`](https://python-all.ru/3.4/library/numbers.html#numbers.Complex) ([`complex`](https://python-all.ru/3.4/library/functions.html#complex))**8081Они представляют комплексные числа как пару машинных чисел с плавающей запятой двойной точности. К ним применимы те же предостережения, что и к числам с плавающей запятой. Действительная и мнимая части комплексного числа `z` могут быть получены через атрибуты только для чтения `z.real` и `z.imag`.8283**Последовательности**8485Они представляют конечные упорядоченные наборы, индексируемые неотрицательными числами. Встроенная функция [`len()`](https://python-all.ru/3.4/library/functions.html#len) возвращает количество элементов последовательности. Когда длина последовательности равна *n*, набор индексов содержит числа 0, 1, ..., *n*-1. Элемент *i* последовательности *a* выбирается как `a[i]`.8687Последовательности также поддерживают срезы: `a[i:j]` выбирает все элементы с индексом *k* таким, что *i* `<=` *k* `<` *j*. При использовании в качестве выражения срез является последовательностью того же типа. Это означает, что набор индексов перенумеровывается, начиная с 0.8889Некоторые последовательности также поддерживают «расширенные срезы» с третьим параметром «шаг»: `a[i:j:k]` выбирает все элементы *a* с индексом *x*, где `x = i + n*k`, *n* `>=` `0` и *i* `<=` *x* `<` *j*.9091Последовательности различаются по изменяемости:9293**Неизменяемые последовательности**9495Объект неизменяемого типа последовательности не может измениться после создания. (Если объект содержит ссылки на другие объекты, эти другие объекты могут быть изменяемыми и могут изменяться; однако совокупность объектов, на которые непосредственно ссылается неизменяемый объект, измениться не может.)9697Следующие типы являются неизменяемыми последовательностями:9899**Строки**100101Строка – это последовательность значений, представляющих кодовые точки Unicode. Все кодовые точки в диапазоне `U+0000 - U+10FFFF` могут быть представлены в строке. В Python нет типа `char`; вместо этого каждая кодовая точка в строке представляется как строковый объект длины `1`. Встроенная функция [`ord()`](https://python-all.ru/3.4/library/functions.html#ord) преобразует кодовую точку из её строковой формы в целое число в диапазоне `0 - 10FFFF`; [`chr()`](https://python-all.ru/3.4/library/functions.html#chr) преобразует целое число в диапазоне `0 - 10FFFF` в соответствующий строковый объект длины `1`. [`str.encode()`](https://python-all.ru/3.4/library/stdtypes.html#str.encode) можно использовать для преобразования [`str`](https://python-all.ru/3.4/library/stdtypes.html#str) в [`bytes`](https://python-all.ru/3.4/library/functions.html#bytes) с использованием заданной текстовой кодировки, а [`bytes.decode()`](https://python-all.ru/3.4/library/stdtypes.html#bytes.decode) можно использовать для обратного преобразования.102103**Кортежи**104105Элементами кортежа могут быть произвольные объекты Python. Кортежи из двух и более элементов создаются списками выражений, разделённых запятыми. Кортеж из одного элемента («синглтон») можно создать, добавив запятую к выражению (выражение само по себе не создаёт кортеж, так как круглые скобки должны использоваться для группировки выражений). Пустой кортеж создаётся пустой парой круглых скобок.106107**Байты**108109Объект bytes является неизменяемым массивом. Элементами являются 8-битные байты, представленные целыми числами в диапазоне 0 \<= x \< 256. Литералы bytes (например, `b'abc'`) и встроенная функция [`bytes()`](https://python-all.ru/3.4/library/functions.html#bytes) могут использоваться для создания объектов bytes. Кроме того, объекты bytes можно декодировать в строки с помощью метода [`decode()`](https://python-all.ru/3.4/library/stdtypes.html#bytes.decode).110111**Изменяемые последовательности**112113Изменяемые последовательности могут быть изменены после создания. Обозначения индексации и срезов могут использоваться в качестве цели операторов присваивания и [`del`](https://python-all.ru/3.4/reference/simple_stmts.html#del) (удаления).114115В настоящее время существует два встроенных изменяемых типа последовательностей:116117**Списки**118119Элементами списка являются произвольные объекты Python. Списки создаются путём помещения списка выражений, разделённых запятыми, в квадратные скобки. (Обратите внимание, что для создания списков длины 0 или 1 не требуется особых случаев.)120121**Байтовые массивы**122123Объект bytearray является изменяемым массивом. Они создаются с помощью встроенного конструктора [`bytearray()`](https://python-all.ru/3.4/library/functions.html#bytearray). Помимо изменяемости (и, следовательно, невозможности хеширования), bytearray в остальном предоставляет тот же интерфейс и функциональность, что и неизменяемые объекты bytes.124125Модуль расширения [`array`](https://python-all.ru/3.4/library/array.html#module-array) предоставляет дополнительный пример изменяемого типа последовательности, как и модуль [`collections`](https://python-all.ru/3.4/library/collections.html#module-collections).126127**Типы множеств**128129Они представляют неупорядоченные, конечные множества уникальных неизменяемых объектов. Как таковые, они не могут индексироваться по подстроке. Однако по ним можно итерироваться, а встроенная функция [`len()`](https://python-all.ru/3.4/library/functions.html#len) возвращает количество элементов в множестве. Обычные применения множеств – быстрая проверка принадлежности, удаление дубликатов из последовательности и вычисление математических операций, таких как пересечение, объединение, разность и симметрическая разность.130131Для элементов множества действуют те же правила неизменяемости, что и для ключей словаря. Обратите внимание, что числовые типы следуют обычным правилам числового сравнения: если два числа считаются равными (например, `1` и `1.0`), только одно из них может содержаться в множестве.132133В настоящее время существует два встроенных типа множеств:134135**Множества**136137Они представляют изменяемое множество. Создаются с помощью встроенного конструктора [`set()`](https://python-all.ru/3.4/library/stdtypes.html#set) и могут быть изменены впоследствии несколькими методами, например [`add()`](https://python-all.ru/3.4/library/stdtypes.html#set.add).138139**Неизменяемые множества**140141Они представляют неизменяемое множество. Создаются встроенным конструктором [`frozenset()`](https://python-all.ru/3.4/library/stdtypes.html#frozenset). Поскольку frozenset неизменяем и [*хэшируем*](https://python-all.ru/3.4/glossary.html#term-hashable), его можно использовать как элемент другого множества или как ключ словаря.142143**Отображения**144145Они представляют конечные множества объектов, индексируемых произвольными наборами индексов. Обозначение индекса `a[k]` выбирает элемент по индексу `k` из отображения `a`; это можно использовать в выражениях, а также как цель присваивания или оператора [`del`](https://python-all.ru/3.4/reference/simple_stmts.html#del). Встроенная функция [`len()`](https://python-all.ru/3.4/library/functions.html#len) возвращает количество элементов в отображении.146147В настоящее время существует один встроенный тип отображения:148149**Словари**150151Они представляют конечные наборы объектов, индексированных почти произвольными значениями. Единственные типы значений, неприемлемые в качестве ключей, – это значения, содержащие списки, словари или другие изменяемые типы, которые сравниваются по значению, а не по идентичности объекта. Причина в том, что эффективная реализация словарей требует, чтобы хеш-значение ключа оставалось постоянным. Числовые типы, используемые для ключей, подчиняются обычным правилам числового сравнения: если два числа считаются равными (например, `1` и `1.0`), то они могут использоваться взаимозаменяемо для индексации одной и той же записи словаря.152153Словари изменяемы; их можно создать с помощью обозначения `{...}` (см. раздел [*Отображения словарей*](https://python-all.ru/3.4/reference/expressions.html#dict)).154155Модули расширения [`dbm.ndbm`](https://python-all.ru/3.4/library/dbm.html#module-dbm.ndbm) и [`dbm.gnu`](https://python-all.ru/3.4/library/dbm.html#module-dbm.gnu) предоставляют дополнительные примеры типов отображений, как и модуль [`collections`](https://python-all.ru/3.4/library/collections.html#module-collections).156157**Вызываемые типы**158159Это типы, к которым применима операция вызова функции (см. раздел [*Вызовы*](https://python-all.ru/3.4/reference/expressions.html#calls)):160161**Определяемые пользователем функции**162163Объект пользовательской функции создаётся определением функции (см. раздел [*Определения функций*](https://python-all.ru/3.4/reference/compound_stmts.html#function)). Она должна вызываться со списком аргументов, содержащим то же количество элементов, что и список формальных параметров функции.164165Специальные атрибуты:166167| Атрибут | Значение |  |168| --- | --- | --- |169| `__doc__` | Строка документации функции, или `None`, если недоступна; не наследуется подклассами | Доступно для записи |170| [`__name__`](https://python-all.ru/3.4/reference/import.html#__name__) | Имя функции | Доступно для записи |171| `__qualname__` | [*Полное имя*](https://python-all.ru/3.4/glossary.html#term-qualified-name) функции Новое в версии 3.3. | Доступно для записи |172| `__module__` | Имя модуля, в котором была определена функция, или `None`, если недоступно | Доступно для записи |173| `__defaults__` | Кортеж, содержащий значения аргументов по умолчанию для тех аргументов, у которых есть значения по умолчанию, или `None`, если ни один аргумент не имеет значения по умолчанию | Доступно для записи |174| `__code__` | Объект кода, представляющий скомпилированное тело функции. | Доступно для записи |175| `__globals__` | Ссылка на словарь, содержащий глобальные переменные функции – глобальное пространство имён модуля, в котором функция была определена. | Только для чтения |176| `__dict__` | Пространство имён, поддерживающее произвольные атрибуты функции. | Доступно для записи |177| `__closure__` | `None` или кортеж ячеек, содержащих привязки для свободных переменных функции | Только для чтения |178| `__annotations__` | Словарь, содержащий аннотации параметров. Ключами словаря являются имена параметров, а `'return'` – для аннотации возвращаемого значения, если она указана | Доступно для записи |179| `__kwdefaults__` | Словарь, содержащий значения по умолчанию для параметров, передаваемых только по ключу. | Доступно для записи |180181Большинство атрибутов, помеченных как «Доступно для записи», проверяют тип присваиваемого значения.182183Объекты функций также поддерживают получение и установку произвольных атрибутов, которые можно использовать, например, для присоединения метаданных к функциям. Для получения и установки таких атрибутов используется обычная точечная нотация. *Обратите внимание, что текущая реализация поддерживает атрибуты функций только для пользовательских функций. Атрибуты функций для встроенных функций могут быть добавлены в будущем.*184185Дополнительную информацию об определении функции можно получить из её объекта code; см. описание внутренних типов ниже.186187**Методы экземпляра**188189Объект метода экземпляра сочетает в себе класс, экземпляр класса и любой вызываемый объект (обычно функцию, определённую пользователем).190191Специальные атрибуты только для чтения: `__self__` – это объект экземпляра класса, `__func__` – объект функции; `__doc__` – документация метода (то же, что `__func__.__doc__`); [`__name__`](https://python-all.ru/3.4/reference/import.html#__name__) – имя метода (то же, что `__func__.__name__`); `__module__` – имя модуля, в котором был определён метод, или `None`, если недоступно192193Методы также поддерживают доступ (но не установку) произвольных атрибутов функции на базовом объекте функции.194195Объекты пользовательских методов могут создаваться при получении атрибута класса (возможно, через экземпляр этого класса), если этот атрибут является пользовательским объектом функции или объектом метода класса.196197Когда объект метода экземпляра создаётся путём получения определённого пользователем объекта функции из класса через один из его экземпляров, его атрибут `__self__` является экземпляром, и говорят, что метод является привязанным. Атрибут `__func__` нового метода – это исходный объект функции198199Когда объект определённого пользователем метода создаётся путём получения другого объекта метода из класса или экземпляра, поведение такое же, как для объекта функции, за исключением того, что атрибут `__func__` нового экземпляра – это не исходный объект метода, а его атрибут `__func__`200201Когда объект метода экземпляра создаётся путём получения объекта метода класса из класса или экземпляра, его атрибут `__self__` – это сам класс, а его атрибут `__func__` – это объект функции, лежащий в основе метода класса202203При вызове объекта метода экземпляра вызывается нижележащая функция (`__func__`), при этом экземпляр класса (`__self__`) вставляется перед списком аргументов. Например, когда `C` – это класс, содержащий определение функции `f()`, и `x` – это экземпляр `C`, вызов `x.f(1)` эквивалентен вызову `C.f(x, 1)`204205Когда объект метода экземпляра создаётся из объекта метода класса, «экземпляр класса», хранящийся в `__self__`, на самом деле будет самим классом, так что вызов `x.f(1)` или `C.f(1)` эквивалентен вызову `f(C,1)`, где `f` – это нижележащая функция206207Обратите внимание, что преобразование объекта функции в объект метода экземпляра происходит каждый раз при получении атрибута из экземпляра. В некоторых случаях полезной оптимизацией является присвоение атрибута локальной переменной и вызов этой локальной переменной. Также заметьте, что это преобразование происходит только для пользовательских функций; другие вызываемые объекты (и все невызываемые объекты) извлекаются без преобразования. Важно также отметить, что пользовательские функции, которые являются атрибутами экземпляра класса, не преобразуются в связанные методы; это происходит *только*, когда функция является атрибутом класса.208209**Функции-генераторы**210211Функция или метод, использующие оператор [`yield`](https://python-all.ru/3.4/reference/simple_stmts.html#yield) (см. раздел [*Оператор yield*](https://python-all.ru/3.4/reference/simple_stmts.html#yield)), называется *функцией-генератором*. Такая функция при вызове всегда возвращает объект-итератор, который можно использовать для выполнения тела функции: вызов метода [`iterator.__next__()`](https://python-all.ru/3.4/library/stdtypes.html#iterator.__next__) итератора приведёт к выполнению функции до тех пор, пока она не предоставит значение с помощью оператора [`yield`](https://python-all.ru/3.4/reference/simple_stmts.html#yield). Когда функция выполняет оператор [`return`](https://python-all.ru/3.4/reference/simple_stmts.html#return) или достигает конца, возбуждается исключение [`StopIteration`](https://python-all.ru/3.4/library/exceptions.html#StopIteration), и итератор достигает конца набора значений для возврата212213**Встроенные функции**214215Объект встроенной функции – это обёртка вокруг функции на C. Примеры встроенных функций: [`len()`](https://python-all.ru/3.4/library/functions.html#len) и [`math.sin()`](https://python-all.ru/3.4/library/math.html#math.sin) ([`math`](https://python-all.ru/3.4/library/math.html#module-math) – это стандартный встроенный модуль). Количество и тип аргументов определяются функцией на C. Специальные атрибуты только для чтения: `__doc__` – строка документации функции, или `None`, если недоступна; [`__name__`](https://python-all.ru/3.4/reference/import.html#__name__) – имя функции; `__self__` установлен в `None` (но см. следующий пункт); `__module__` – имя модуля, в котором функция была определена, или `None`, если недоступно216217**Встроенные методы**218219По сути, это другая разновидность встроенной функции, на этот раз содержащая объект, передаваемый функции на C как неявный дополнительный аргумент. Пример встроенного метода: `alist.append()`, если предположить, что *alist* – это объект списка. В этом случае специальный атрибут только для чтения `__self__` устанавливается на объект, обозначаемый *alist*220221**Классы**222223Классы вызываемы. Обычно эти объекты действуют как фабрики для создания новых экземпляров самих себя, но возможны варианты для типов классов, которые переопределяют224225[`__new__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__new__)226227. Аргументы вызова передаются в228229[`__new__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__new__)230231и, в типичном случае, в232233[`__init__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__init__)234235для инициализации нового экземпляра236237**Экземпляры классов**238239Экземпляры произвольных классов можно сделать вызываемыми, определив метод240241[`__call__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__call__)242243в их классе244245**Модули**246247Модули – это базовая организационная единица кода Python, и они создаются системой [*импорта*](https://python-all.ru/3.4/reference/import.html#importsystem), вызываемой либо оператором [`import`](https://python-all.ru/3.4/reference/simple_stmts.html#import) (см. [`import`](https://python-all.ru/3.4/reference/simple_stmts.html#import)), либо вызовом таких функций, как [`importlib.import_module()`](https://python-all.ru/3.4/library/importlib.html#importlib.import_module) и встроенной [`__import__()`](https://python-all.ru/3.4/library/functions.html#__import__). Объект модуля имеет пространство имён, реализованное объектом-словарём (это словарь, на который ссылается атрибут `__globals__` функций, определённых в модуле). Обращения к атрибутам преобразуются в поиск в этом словаре, например, `m.x` эквивалентно `m.__dict__["x"]`. Объект модуля не содержит объект кода, использованный для инициализации модуля (поскольку после инициализации он не нужен)248249Присваивание атрибуту обновляет словарь пространства имён модуля, например, `m.x = 1` эквивалентно `m.__dict__["x"] = 1`250251Специальный атрибут только для чтения: `__dict__` – это пространство имён модуля в виде объекта словаря.252253**Особенность реализации CPython:** Из-за того, как CPython очищает словари модулей, словарь модуля будет очищен, когда модуль выйдет из области видимости, даже если на словарь ещё есть активные ссылки. Чтобы этого избежать, скопируйте словарь или держите модуль в памяти, пока используете его словарь напрямую.254255Предопределённые (изменяемые) атрибуты: [`__name__`](https://python-all.ru/3.4/reference/import.html#__name__) – имя модуля; `__doc__` – строка документации модуля, или `None`, если недоступна; [`__file__`](https://python-all.ru/3.4/reference/import.html#__file__) – путь к файлу, из которого был загружен модуль, если он был загружен из файла. Атрибут [`__file__`](https://python-all.ru/3.4/reference/import.html#__file__) может отсутствовать для некоторых типов модулей, например для модулей C, статически слинкованных с интерпретатором; для расширений, динамически загружаемых из разделяемой библиотеки, это путь к файлу разделяемой библиотеки.256257**Пользовательские классы**258259Пользовательские типы классов обычно создаются определениями классов (см. раздел [*Определения классов*](https://python-all.ru/3.4/reference/compound_stmts.html#class)). Класс имеет пространство имён, реализованное через объект словаря. Ссылки на атрибуты класса преобразуются в поиск в этом словаре, например, `C.x` преобразуется в `C.__dict__["x"]` (хотя есть ряд перехватчиков, позволяющих другие способы поиска атрибутов). Когда атрибут не найден там, поиск продолжается в базовых классах. Этот поиск по базовым классам использует порядок разрешения методов C3, который корректно работает даже в присутствии «ромбовидных» структур наследования, где несколько путей наследования ведут к общему предку. Дополнительные сведения о C3 MRO, используемом в Python, можно найти в документации к версии 2.3 по адресу [https://www.python.org/download/releases/2.3/mro/](https://python-all.ru/3.4/reference/datamodel.html).260261Когда ссылка на атрибут класса (для класса `C`, скажем) возвращает объект метода класса, он преобразуется в объект метода экземпляра, атрибут `__self__` которого равен `C`. Когда возвращается объект статического метода, он преобразуется в объект, обёрнутый этим статическим методом. См. раздел [*Реализация дескрипторов*](https://python-all.ru/3.4/reference/datamodel.html#descriptors) для другого способа, которым атрибуты, извлекаемые из класса, могут отличаться от тех, что фактически содержатся в его `__dict__`.262263Присваивание атрибутов класса обновляет словарь самого класса, но никогда не словарь базового класса.264265Объект класса можно вызвать (см. выше), чтобы получить экземпляр класса (см. ниже).266267Специальные атрибуты: [`__name__`](https://python-all.ru/3.4/reference/import.html#__name__) – имя класса; `__module__` – имя модуля, в котором определён класс; `__dict__` – словарь, содержащий пространство имён класса; [`__bases__`](https://python-all.ru/3.4/library/stdtypes.html#class.__bases__) – кортеж (возможно, пустой или из одного элемента) с базовыми классами в порядке их появления в списке базовых классов; `__doc__` – строка документации класса или None, если не определена.268269**Экземпляры классов**270271Экземпляр класса создаётся вызовом объекта класса (см. выше). Экземпляр класса имеет пространство имён, реализованное в виде словаря, который является первым местом поиска ссылок на атрибуты. Когда атрибут не найден там, а у класса экземпляра есть атрибут с таким именем, поиск продолжается среди атрибутов класса. Если найденный атрибут класса – это объект пользовательской функции, он преобразуется в объект метода экземпляра, атрибут `__self__` которого указывает на экземпляр. Объекты статических методов и методов класса также преобразуются; см. выше раздел «Классы». Другой способ, которым атрибуты класса, получаемые через его экземпляры, могут отличаться от реально хранящихся в `__dict__` класса, описан в разделе [*Реализация дескрипторов*](https://python-all.ru/3.4/reference/datamodel.html#descriptors). Если атрибут класса не найден, а у объекта класса есть метод [`__getattr__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__getattr__), он вызывается для завершения поиска.272273Назначение и удаление атрибутов изменяют словарь экземпляра, но никогда не словарь класса. Если у класса есть метод [`__setattr__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__setattr__) или [`__delattr__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__delattr__), он вызывается вместо прямого изменения словаря экземпляра.274275Экземпляры классов могут вести себя как числа, последовательности или отображения, если у них есть методы с определёнными специальными именами. См. раздел [*Имена специальных методов*](https://python-all.ru/3.4/reference/datamodel.html#specialnames).276277Специальные атрибуты: [`__dict__`](https://python-all.ru/3.4/library/stdtypes.html#object.__dict__) – словарь атрибутов; [`__class__`](https://python-all.ru/3.4/library/stdtypes.html#instance.__class__) – класс экземпляра.278279**Объекты ввода-вывода (также известные как файловые объекты)**280281Объект [*файла*](https://python-all.ru/3.4/glossary.html#term-file-object) представляет открытый файл. Существуют различные сокращённые способы создания файловых объектов: встроенная функция [`open()`](https://python-all.ru/3.4/library/functions.html#open), а также [`os.popen()`](https://python-all.ru/3.4/library/os.html#os.popen), [`os.fdopen()`](https://python-all.ru/3.4/library/os.html#os.fdopen) и метод [`makefile()`](https://python-all.ru/3.4/library/socket.html#socket.socket.makefile) объектов сокетов (возможно, и другие функции или методы, предоставляемые расширениями).282283Объекты `sys.stdin`, `sys.stdout` и `sys.stderr` инициализируются как файловые объекты, соответствующие стандартному потоку ввода, вывода и ошибок интерпретатора; все они открыты в текстовом режиме и, следовательно, следуют интерфейсу, определённому абстрактным классом [`io.TextIOBase`](https://python-all.ru/3.4/library/io.html#io.TextIOBase).284285**Внутренние типы**286287Некоторые типы, используемые внутри интерпретатора, доступны пользователю. Их определения могут измениться в будущих версиях интерпретатора, но здесь они упомянуты для полноты.288289**Объекты кода**290291Объекты кода представляют собой *скомпилированный в байт-код* исполняемый код Python, или [*байт-код*](https://python-all.ru/3.4/glossary.html#term-bytecode). Разница между объектом кода и объектом функции в том, что объект функции содержит явную ссылку на глобальные переменные функции (модуль, в котором она определена), тогда как объект кода не содержит контекста; кроме того, значения аргументов по умолчанию хранятся в объекте функции, а не в объекте кода (поскольку они представляют значения, вычисляемые во время выполнения). В отличие от объектов функций, объекты кода неизменяемы и не содержат ссылок (прямых или косвенных) на изменяемые объекты.292293Специальные атрибуты только для чтения: `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` – целое число, кодирующее ряд флагов для интерпретатора.294295Для `co_flags` определены следующие биты флагов: бит `0x04` установлен, если функция использует синтаксис `*arguments` для приёма произвольного количества позиционных аргументов; бит `0x08` установлен, если функция использует синтаксис `**keywords` для приёма произвольных именованных аргументов; бит `0x20` установлен, если функция является генератором.296297Объявления будущих возможностей (`from __future__ import division`) также используют биты в `co_flags`, чтобы указать, был ли объект кода скомпилирован с определённой включённой возможностью: бит `0x2000` установлен, если функция была скомпилирована с включённым future division; биты `0x10` и `0x1000` использовались в более ранних версиях Python.298299Остальные биты в `co_flags` зарезервированы для внутреннего использования.300301Если объект кода представляет функцию, первый элемент в `co_consts` – это строка документации функции или `None`, если не определена.302303**Объекты фреймов**304305Объекты фреймов представляют фреймы выполнения. Они могут встречаться в объектах трассировки стека (см. ниже).306307Специальные атрибуты только для чтения: `f_back` – ссылка на предыдущий фрейм стека (в сторону вызвавшего), или `None`, если это нижний фрейм; `f_code` – объект кода, выполняемый в этом фрейме; `f_locals` – словарь, используемый для поиска локальных переменных; `f_globals` – словарь для глобальных переменных; `f_builtins` – словарь для встроенных имён; `f_lasti` – точная инструкция (индекс в строке байткода объекта кода).308309Специальные изменяемые атрибуты: `f_trace`, если не `None`, – это функция, вызываемая в начале каждой строки исходного кода (используется отладчиком); `f_lineno` – текущий номер строки фрейма – запись в него изнутри трассировочной функции переходит на указанную строку (только для самого нижнего фрейма). Отладчик может реализовать команду Jump (также называемую Set Next Statement) записью в f\_lineno.310311Объекты Frame поддерживают один метод:312313#### `frame.clear()`314315Этот метод очищает все ссылки на локальные переменные, хранящиеся во фрейме. Кроме того, если фрейм принадлежал генератору, генератор финализируется. Это помогает разорвать циклические ссылки с участием объектов фреймов (например, при перехвате исключения и сохранении его трассировки для дальнейшего использования).316317[`RuntimeError`](https://python-all.ru/3.4/library/exceptions.html#RuntimeError) возбуждается, если фрейм в данный момент выполняется.318319Новое в версии 3.4.320321**Объекты трассировки стека**322323Объекты traceback представляют стек вызовов исключения. Объект traceback создаётся при возникновении исключения. Когда поиск обработчика исключения разворачивает стек выполнения, на каждом раскрученном уровне объект traceback вставляется перед текущим traceback. Когда обработчик исключения входит в работу, стек вызовов становится доступен программе. (См. раздел [*Оператор try*](https://python-all.ru/3.4/reference/compound_stmts.html#try).) Он доступен как третий элемент кортежа, возвращаемого `sys.exc_info()`. Когда программа не содержит подходящего обработчика, стек вызовов выводится (в отформатированном виде) в стандартный поток ошибок; если интерпретатор работает в интерактивном режиме, он также становится доступен пользователю как `sys.last_traceback`.324325Специальные атрибуты только для чтения: `tb_next` – следующий уровень в стеке вызовов (в сторону фрейма, где произошло исключение), или `None`, если следующего уровня нет; `tb_frame` указывает на фрейм выполнения текущего уровня; `tb_lineno` – номер строки, в которой произошло исключение; `tb_lasti` – точная инструкция. Номер строки и последняя инструкция в traceback могут отличаться от номера строки его объекта фрейма, если исключение произошло в операторе [`try`](https://python-all.ru/3.4/reference/compound_stmts.html#try) без подходящего except-предложения или с finally-предложением.326327**Объекты срезов**328329Объекты срезов используются для представления срезов в методах [`__getitem__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__getitem__). Они также создаются встроенной функцией [`slice()`](https://python-all.ru/3.4/library/functions.html#slice).330331Специальные атрибуты только для чтения: `start` – нижняя граница; `stop` – верхняя граница; `step` – шаг; каждый равен `None`, если опущен. Эти атрибуты могут иметь любой тип.332333Объекты slice поддерживают один метод:334335#### `slice.indices(self, length)`336337Этот метод принимает единственный целочисленный аргумент *length* и вычисляет информацию о срезе, который объект среза описывал бы, если бы был применен к последовательности из *length* элементов. Он возвращает кортеж из трех целых чисел; соответственно это индексы *start* и *stop*, а также *step* или длина шага среза. Пропущенные или выходящие за границы индексы обрабатываются так же, как и для обычных срезов.338339**Объекты статических методов**340341Статические методы предоставляют способ предотвратить преобразование объектов функций в объекты методов, описанное выше. Объект статического метода – это обёртка вокруг любого другого объекта, обычно пользовательского метода. Когда объект статического метода извлекается из класса или экземпляра класса, фактически возвращается обёрнутый объект, который не подвергается дальнейшим преобразованиям. Сами объекты статических методов не являются вызываемыми, хотя объекты, которые они оборачивают, обычно вызываемы. Объекты статических методов создаются встроенным конструктором342343[`staticmethod()`](https://python-all.ru/3.4/library/functions.html#staticmethod)344345.346347**Объекты методов классов**348349Объект метода класса, как и объект статического метода, является обёрткой вокруг другого объекта, изменяющей способ извлечения этого объекта из классов и экземпляров классов. Поведение объектов методов класса при таком извлечении описано выше, в разделе «Пользовательские методы». Объекты методов класса создаются встроенным конструктором350351[`classmethod()`](https://python-all.ru/3.4/library/functions.html#classmethod)352353.354355## 3.3. Имена специальных методов356357Класс может реализовать определённые операции, вызываемые специальным синтаксисом (например, арифметические операции или индексация и срезы), определяя методы со специальными именами. Это подход Python к *перегрузке операторов*, позволяющий классам определять собственное поведение в отношении операторов языка. Например, если класс определяет метод с именем [`__getitem__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__getitem__), и `x` – экземпляр этого класса, то `x[i]` примерно эквивалентно `type(x).__getitem__(x, i)`. Если не указано иное, попытка выполнить операцию при отсутствии соответствующего метода вызывает исключение (обычно [`AttributeError`](https://python-all.ru/3.4/library/exceptions.html#AttributeError) или [`TypeError`](https://python-all.ru/3.4/library/exceptions.html#TypeError)).358359При реализации класса, эмулирующего какой-либо встроенный тип, важно, чтобы эмуляция была реализована лишь в той степени, в которой это имеет смысл для моделируемого объекта. Например, некоторые последовательности могут хорошо работать с извлечением отдельных элементов, но извлечение среза может не иметь смысла. (Один из примеров – интерфейс `NodeList` в объектной модели документов W3C.)360361### 3.3.1. Базовая настройка362363#### `object.__new__(cls[, ...])`364365Вызывается для создания нового экземпляра класса *cls*. [`__new__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__new__) – это статический метод (обрабатывается особым образом, так что объявлять его таковым не требуется), который первым аргументом принимает класс, экземпляр которого запрашивается. Остальные аргументы – те, что переданы выражению конструктора объекта (вызову класса). Возвращаемое значение [`__new__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__new__) должно быть новым экземпляром объекта (обычно экземпляром *cls*).366367Типичные реализации создают новый экземпляр класса, вызывая метод [`__new__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__new__) суперкласса через `super(currentclass, cls).__new__(cls[, ...])` с соответствующими аргументами, а затем модифицируя вновь созданный экземпляр по мере необходимости перед возвратом.368369Если [`__new__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__new__) возвращает экземпляр *cls*, то метод [`__init__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__init__) нового экземпляра будет вызван как `__init__(self[, ...])`, где *self* – новый экземпляр, а остальные аргументы – те же, что были переданы в [`__new__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__new__).370371Если [`__new__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__new__) не возвращает экземпляр *cls*, то метод [`__init__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__init__) нового экземпляра не будет вызван.372373[`__new__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__new__) в первую очередь предназначен для того, чтобы подклассы неизменяемых типов (например, int, str или tuple) могли настраивать создание экземпляров. Он также часто переопределяется в пользовательских метаклассах для настройки создания классов.374375#### `object.__init__(self[, ...])`376377Вызывается после создания экземпляра (с помощью [`__new__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__new__)), но до его возврата вызывающему коду. Аргументы – это те, что были переданы в выражение конструктора класса. Если базовый класс имеет метод [`__init__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__init__), то метод [`__init__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__init__) производного класса (если он есть) должен явно вызвать его, чтобы обеспечить правильную инициализацию базовой части экземпляра; например: `BaseClass.__init__(self, [args...])`.378379Поскольку [`__new__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__new__) и [`__init__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__init__) работают вместе при создании объектов ([`__new__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__new__) создает объект, а [`__init__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__init__) настраивает его), [`__init__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__init__) не может возвращать никакое значение, кроме `None`; попытка вернуть другое значение приведет к возбуждению [`TypeError`](https://python-all.ru/3.4/library/exceptions.html#TypeError) во время выполнения.380381#### `object.__del__(self)`382383Вызывается, когда экземпляр собирается быть уничтожен. Это также называется деструктором. Если базовый класс имеет метод [`__del__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__del__), то метод [`__del__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__del__) производного класса (если он есть) должен явно вызвать его, чтобы обеспечить правильное удаление базовой части экземпляра. Обратите внимание, что метод [`__del__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__del__) может (хотя это и не рекомендуется!) отложить уничтожение экземпляра, создав на него новую ссылку. Тогда он будет вызван позже, когда эта новая ссылка будет удалена. Не гарантируется, что методы [`__del__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__del__) будут вызваны для объектов, которые все еще существуют при завершении интерпретатора.384385> **Примечание**386>387> `del x` не вызывает напрямую `x.__del__()` – первая конструкция уменьшает счетчик ссылок на `x` на единицу, а вторая вызывается только когда счетчик ссылок `x` достигает нуля. Некоторые распространенные ситуации, которые могут помешать счетчику ссылок объекта обнулиться, включают: циклические ссылки между объектами (например, двусвязный список или древовидная структура данных с указателями на родителя и потомков); ссылка на объект в стековом фрейме функции, перехватившей исключение (объект traceback, хранящийся в `sys.exc_info()[2]`, удерживает стековый фрейм в живых); или ссылка на объект в стековом фрейме, который возбудил необработанное исключение в интерактивном режиме (объект traceback, хранящийся в `sys.last_traceback`, удерживает стековый фрейм в живых). Первая ситуация исправляется только явным разрывом циклов; вторая – освобождением ссылки на объект traceback, когда он больше не нужен; третья – записью `None` в `sys.last_traceback`. Циклические ссылки, ставшие мусором, обнаруживаются и уничтожаются, когда циклический сборщик мусора включен (по умолчанию он включен). Обратитесь к документации модуля [`gc`](https://python-all.ru/3.4/library/gc.html#module-gc) для получения дополнительной информации по этой теме.388389> **Предупреждение**390>391> Из-за ненадежных обстоятельств, при которых вызываются методы [`__del__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__del__), исключения, возникающие во время их выполнения, игнорируются, а вместо этого предупреждение выводится в `sys.stderr`. Кроме того, когда [`__del__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__del__) вызывается в ответ на удаление модуля (например, при завершении программы), другие глобальные переменные, на которые ссылается метод [`__del__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__del__), могут уже быть удалены или находиться в процессе уничтожения (например, механизм импорта завершает работу). По этой причине методы [`__del__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__del__) должны делать абсолютный минимум, необходимый для поддержания внешних инвариантов. Начиная с версии 1.5, Python гарантирует, что глобальные переменные, имена которых начинаются с одного подчеркивания, удаляются из своего модуля до удаления других глобальных переменных; если других ссылок на такие глобалы не существует, это может помочь обеспечить доступность импортированных модулей на момент вызова метода [`__del__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__del__).392393#### `object.__repr__(self)`394395Вызывается встроенной функцией [`repr()`](https://python-all.ru/3.4/library/functions.html#repr) для вычисления «официального» строкового представления объекта. По возможности это представление должно выглядеть как допустимое выражение Python, которое можно использовать для воссоздания объекта с тем же значением (при наличии подходящего окружения). Если это невозможно, следует вернуть строку вида `<...какое-нибудь полезное описание...>`. Возвращаемое значение должно быть строкой. Если класс определяет [`__repr__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__repr__), но не [`__str__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__str__), то [`__repr__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__repr__) также используется, когда требуется «неформальное» строковое представление экземпляров этого класса.396397Обычно используется для отладки, поэтому важно, чтобы представление было информативным и однозначным.398399#### `object.__str__(self)`400401Вызывается [`str(object)`](https://python-all.ru/3.4/library/stdtypes.html#str) и встроенными функциями [`format()`](https://python-all.ru/3.4/library/functions.html#format) и [`print()`](https://python-all.ru/3.4/library/functions.html#print) для вычисления «неформального» или удобного для печати строкового представления объекта. Возвращаемое значение должно быть объектом [*string*](https://python-all.ru/3.4/library/stdtypes.html#textseq).402403Этот метод отличается от [`object.__repr__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__repr__) тем, что от [`__str__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__str__) не требуется возвращать допустимое выражение Python: можно использовать более удобное или краткое представление.404405Реализация по умолчанию, определенная встроенным типом [`object`](https://python-all.ru/3.4/library/functions.html#object), вызывает [`object.__repr__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__repr__).406407#### `object.__bytes__(self)`408409Вызывается [`bytes()`](https://python-all.ru/3.4/library/functions.html#bytes) для вычисления байтового строкового представления объекта. Должен возвращать объект `bytes`.410411#### `object.__format__(self, format_spec)`412413Вызывается встроенной функцией [`format()`](https://python-all.ru/3.4/library/functions.html#format) (и, соответственно, методом [`str.format()`](https://python-all.ru/3.4/library/stdtypes.html#str.format) класса [`str`](https://python-all.ru/3.4/library/stdtypes.html#str)) для получения «форматированного» строкового представления объекта. Аргумент `format_spec` – это строка, описывающая желаемые параметры форматирования. Интерпретация аргумента `format_spec` зависит от типа, реализующего [`__format__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__format__), однако большинство классов либо делегируют форматирование одному из встроенных типов, либо используют аналогичный синтаксис параметров форматирования.414415См. [*мини-язык спецификации формата*](https://python-all.ru/3.4/library/string.html#formatspec) для описания стандартного синтаксиса форматирования.416417Возвращаемое значение должно быть строковым объектом.418419Изменено в версии 3.4: Сам метод \_\_format\_\_ объекта `object` возбуждает [`TypeError`](https://python-all.ru/3.4/library/exceptions.html#TypeError), если в него передана непустая строка.420421#### `object.__lt__(self, other)`422423#### `object.__le__(self, other)`424425#### `object.__eq__(self, other)`426427#### `object.__ne__(self, other)`428429#### `object.__gt__(self, other)`430431#### `object.__ge__(self, other)`432433Это так называемые методы «богатого сравнения». Соответствие между символами операторов и именами методов следующее: `x<y` вызывает `x.__lt__(y)`, `x<=y` вызывает `x.__le__(y)`, `x==y` вызывает `x.__eq__(y)`, `x!=y` вызывает `x.__ne__(y)`, `x>y` вызывает `x.__gt__(y)`, а `x>=y` вызывает `x.__ge__(y)`.434435Метод богатого сравнения может вернуть синглтон `NotImplemented`, если он не реализует операцию для данной пары аргументов. По соглашению, при успешном сравнении возвращаются `False` и `True`. Однако эти методы могут возвращать любое значение, поэтому если оператор сравнения используется в логическом контексте (например, в условии оператора `if`), Python вызовет [`bool()`](https://python-all.ru/3.4/library/functions.html#bool) для этого значения, чтобы определить, истинно оно или ложно.436437По умолчанию [`__ne__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__ne__) делегирует выполнение [`__eq__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__eq__) и инвертирует результат, если только тот не равен `NotImplemented`. Других подразумеваемых связей между операторами сравнения нет; например, истинность `(x<y or x==y)` не влечет за собой `x<=y`. Для автоматической генерации операций упорядочивания из одной корневой операции см. [`functools.total_ordering()`](https://python-all.ru/3.4/library/functools.html#functools.total_ordering).438439См. абзац о [`__hash__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__hash__) для важных замечаний по созданию [*хэшируемых*](https://python-all.ru/3.4/glossary.html#term-hashable) объектов, которые поддерживают пользовательские операции сравнения и могут использоваться в качестве ключей словаря.440441Эти методы не имеют версий с переставленными аргументами (которые используются, когда левый аргумент не поддерживает операцию, а правый поддерживает); вместо этого [`__lt__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__lt__) и [`__gt__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__gt__) являются отражением друг друга, [`__le__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__le__) и [`__ge__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__ge__) – отражение друг друга, а [`__eq__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__eq__) и [`__ne__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__ne__) – собственное отражение. Если операнды разных типов и тип правого операнда является прямым или косвенным подклассом типа левого операнда, приоритет имеет отраженный метод правого операнда; в противном случае приоритет у метода левого операнда. Виртуальное наследование не учитывается.442443#### `object.__hash__(self)`444445Вызывается встроенной функцией [`hash()`](https://python-all.ru/3.4/library/functions.html#hash) и для операций над элементами хешируемых коллекций, включая [`set`](https://python-all.ru/3.4/library/stdtypes.html#set), [`frozenset`](https://python-all.ru/3.4/library/stdtypes.html#frozenset) и [`dict`](https://python-all.ru/3.4/library/stdtypes.html#dict). [`__hash__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__hash__) должна возвращать целое число. Единственное обязательное свойство: объекты, которые равны при сравнении, должны иметь одинаковое хеш-значение; рекомендуется как-то смешивать (например, с помощью исключающего ИЛИ) хеш-значения компонентов объекта, которые также участвуют в сравнении объектов.446447> **Примечание**448>449> [`hash()`](https://python-all.ru/3.4/library/functions.html#hash) усекает значение, возвращаемое пользовательским методом [`__hash__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__hash__) объекта, до размера `Py_ssize_t`. Обычно это 8 байт в 64-битных сборках и 4 байта в 32-битных. Если [`__hash__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__hash__) объекта должен работать в сборках с разной разрядностью, обязательно проверьте разрядность на всех поддерживаемых сборках. Простой способ сделать это – `python -c "import sys; print(sys.hash_info.width)"`.450451Если класс не определяет метод [`__eq__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__eq__), он не должен определять и операцию [`__hash__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__hash__); если он определяет [`__eq__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__eq__), но не [`__hash__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__hash__), его экземпляры нельзя будет использовать как элементы в хешируемых коллекциях. Если класс определяет изменяемые объекты и реализует метод [`__eq__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__eq__), он не должен реализовывать [`__hash__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__hash__), поскольку реализация хешируемых коллекций требует, чтобы хеш-значение ключа было неизменным (если хеш-значение объекта изменится, он окажется не в той хеш-корзине).452453Пользовательские классы по умолчанию имеют методы [`__eq__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__eq__) и [`__hash__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__hash__); с ними все объекты считаются неравными (кроме самих себя), а `x.__hash__()` возвращает подходящее значение, так что `x == y` подразумевает как `x is y`, так и `hash(x) == hash(y)`.454455Класс, который переопределяет [`__eq__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__eq__) и не определяет [`__hash__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__hash__), будет иметь [`__hash__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__hash__), неявно установленный в `None`. Когда метод [`__hash__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__hash__) класса равен `None`, экземпляры класса будут вызывать соответствующее исключение [`TypeError`](https://python-all.ru/3.4/library/exceptions.html#TypeError), когда программа попытается получить их хеш-значение, а также будут правильно идентифицированы как нехешируемые при проверке `isinstance(obj, collections.Hashable)`.456457Если класс, который переопределяет [`__eq__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__eq__), должен сохранить реализацию [`__hash__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__hash__) родительского класса, интерпретатору нужно явно указать это, присвоив `__hash__ = <ParentClass>.__hash__`.458459Если класс, который не переопределяет [`__eq__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__eq__), хочет отключить поддержку хеширования, он должен включить `__hash__ = None` в определение класса. Класс, определяющий собственный [`__hash__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__hash__), который явно вызывает [`TypeError`](https://python-all.ru/3.4/library/exceptions.html#TypeError), будет ошибочно идентифицирован как хешируемый вызовом `isinstance(obj, collections.Hashable)`.460461> **Примечание**462>463> По умолчанию значения [`__hash__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__hash__) объектов str, bytes и datetime «солятся» непредсказуемым случайным значением. Хотя они остаются постоянными в рамках одного процесса Python, их нельзя предсказать между повторными запусками Python.464>465> Это предназначено для защиты от отказа в обслуживании, вызванного специально подобранными входными данными, которые используют наихудшую производительность вставки в dict (сложность O(n^2)). Подробнее см. на [http://www.ocert.org/advisories/ocert-2011-003.html](https://python-all.ru/3.4/reference/datamodel.html).466>467> Изменение хеш-значений влияет на порядок итерации словарей, множеств и других отображений. Python никогда не давал гарантий относительно этого порядка (и он обычно различается в 32-битных и 64-битных сборках).468>469> См. также [`PYTHONHASHSEED`](https://python-all.ru/3.4/using/cmdline.html#envvar-PYTHONHASHSEED).470471Изменено в версии 3.3: Рандомизация хешей включена по умолчанию.472473#### `object.__bool__(self)`474475Вызывается для реализации проверки истинности и встроенной операции `bool()`; должна возвращать `False` или `True`. Если этот метод не определён, вызывается [`__len__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__len__) (если он определён), и объект считается истинным, если его результат не равен нулю. Если класс не определяет ни [`__len__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__len__), ни [`__bool__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__bool__), все его экземпляры считаются истинными.476477### 3.3.2. Настройка доступа к атрибутам478479Следующие методы могут быть определены для настройки смысла доступа к атрибутам (использование, присваивание или удаление `x.name`) для экземпляров классов.480481#### `object.__getattr__(self, name)`482483Вызывается, когда поиск атрибута не нашёл его в обычных местах (то есть это не атрибут экземпляра и он не найден в дереве классов для `self`). `name` – имя атрибута. Этот метод должен возвращать (вычисленное) значение атрибута или вызывать исключение [`AttributeError`](https://python-all.ru/3.4/library/exceptions.html#AttributeError).484485Обратите внимание, что если атрибут найден через обычный механизм, [`__getattr__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__getattr__) не вызывается. (Это намеренная асимметрия между [`__getattr__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__getattr__) и [`__setattr__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__setattr__).) Это сделано как из соображений эффективности, так и потому, что иначе [`__getattr__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__getattr__) не имел бы способа получить доступ к другим атрибутам экземпляра. Также учтите, что по крайней мере для переменных экземпляра можно имитировать полный контроль, не вставляя никакие значения в словарь атрибутов экземпляра (а вставляя их в другой объект). См. метод [`__getattribute__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__getattribute__) ниже, чтобы узнать, как на самом деле получить полный контроль над доступом к атрибутам.486487#### `object.__getattribute__(self, name)`488489Вызывается безусловно для реализации доступа к атрибутам экземпляров класса. Если класс также определяет [`__getattr__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__getattr__), последний не будет вызван, если только [`__getattribute__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__getattribute__) не вызовет его явно или не вызовет исключение [`AttributeError`](https://python-all.ru/3.4/library/exceptions.html#AttributeError). Этот метод должен возвращать (вычисленное) значение атрибута или вызывать исключение [`AttributeError`](https://python-all.ru/3.4/library/exceptions.html#AttributeError). Чтобы избежать бесконечной рекурсии в этом методе, его реализация должна всегда вызывать метод базового класса с тем же именем для доступа к любым необходимым атрибутам, например, `object.__getattribute__(self, name)`.490491> **Примечание**492>493> Этот метод всё равно может быть обойдён при поиске специальных методов в результате неявного вызова через синтаксис языка или встроенные функции. См. [*Поиск специальных методов*](https://python-all.ru/3.4/reference/datamodel.html#special-lookup).494495#### `object.__setattr__(self, name, value)`496497Вызывается при попытке присвоения атрибута. Этот метод вызывается вместо обычного механизма (т.е. сохранения значения в словаре экземпляра). *name* – имя атрибута, *value* – значение, которое ему присваивается.498499Если [`__setattr__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__setattr__) хочет присвоить значение атрибуту экземпляра, он должен вызвать метод базового класса с тем же именем, например, `object.__setattr__(self, name, value)`.500501#### `object.__delattr__(self, name)`502503Действует как [`__setattr__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__setattr__), но для удаления атрибута, а не присваивания. Следует реализовывать только если `del obj.name` имеет смысл для объекта.504505#### `object.__dir__(self)`506507Вызывается, когда для объекта вызывается [`dir()`](https://python-all.ru/3.4/library/functions.html#dir). Должна возвращаться последовательность. [`dir()`](https://python-all.ru/3.4/library/functions.html#dir) преобразует возвращённую последовательность в список и сортирует его.508509#### 3.3.2.1. Реализация дескрипторов510511Следующие методы применяются только тогда, когда экземпляр класса, содержащего метод (так называемый *класс-дескриптор*), появляется в *классе-владельце* (дескриптор должен находиться либо в словаре класса владельца, либо в словаре класса одного из его родителей). В приведённых ниже примерах «атрибут» относится к атрибуту, имя которого является ключом свойства в `__dict__` класса-владельца.512513#### `object.__get__(self, instance, owner)`514515Вызывается для получения атрибута класса-владельца (доступ к атрибуту класса) или экземпляра этого класса (доступ к атрибуту экземпляра). *owner* всегда является классом-владельцем, а *instance* – экземпляр, через который был получен доступ к атрибуту, или `None`, если атрибут получен через *owner*. Этот метод должен возвращать (вычисленное) значение атрибута или вызывать исключение [`AttributeError`](https://python-all.ru/3.4/library/exceptions.html#AttributeError).516517#### `object.__set__(self, instance, value)`518519Вызывается для установки атрибута экземпляра *instance* класса-владельца в новое значение *value*.520521#### `object.__delete__(self, instance)`522523Вызывается для удаления атрибута экземпляра *instance* класса-владельца.524525Атрибут `__objclass__` интерпретируется модулем [`inspect`](https://python-all.ru/3.4/library/inspect.html#module-inspect) как указывающий на класс, в котором определён этот объект (правильная установка этого атрибута может помочь в интроспекции динамических атрибутов класса во время выполнения). Для вызываемых объектов он может указывать, что ожидается или требуется экземпляр данного типа (или подкласса) в качестве первого позиционного аргумента (например, CPython устанавливает этот атрибут для несвязанных методов, реализованных на C).526527#### 3.3.2.2. Вызов дескрипторов528529В общем случае дескриптор – это атрибут объекта с «поведением привязки», доступ к которому переопределён методами протокола дескриптора: [`__get__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__get__), [`__set__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__set__) и [`__delete__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__delete__). Если для объекта определён хотя бы один из этих методов, он считается дескриптором.530531Поведение по умолчанию для доступа к атрибуту – получить, установить или удалить атрибут из словаря объекта. Например, `a.x` имеет цепочку поиска, начинающуюся с `a.__dict__['x']`, затем `type(a).__dict__['x']`, и продолжающуюся по базовым классам `type(a)`, исключая метаклассы.532533Однако, если найденное значение является объектом, определяющим один из методов дескриптора, то Python может переопределить поведение по умолчанию и вместо этого вызвать метод дескриптора. Где именно это происходит в цепочке приоритетов, зависит от того, какие методы дескриптора определены и как они были вызваны.534535Отправная точка для вызова дескриптора – это привязка, `a.x`. Как собираются аргументы, зависит от `a`.536537**Прямой вызов**538539Самый простой и самый редкий вызов – когда пользовательский код напрямую вызывает метод дескриптора:540541`x.__get__(a)`542543.544545**Привязка к экземпляру**546547При привязке к экземпляру объекта548549`a.x`550551преобразуется в вызов:552553`type(a).__dict__['x'].__get__(a, type(a))`554555.556557**Привязка к классу**558559При привязке к классу560561`A.x`562563преобразуется в вызов:564565`A.__dict__['x'].__get__(None, A)`566567.568569**Привязка через super**570571Если572573`a`574575является экземпляром576577[`super`](https://python-all.ru/3.4/library/functions.html#super)578579, то привязка580581`super(B, obj).m()`582583ищет в584585`obj.__class__.__mro__`586587базовый класс588589`A`590591, непосредственно предшествующий592593`B`594595, и затем вызывает дескриптор вызовом:596597`A.__dict__['m'].__get__(obj, obj.__class__)`598599.600601Для привязок к экземплярам приоритет вызова дескриптора зависит от того, какие методы дескриптора определены. Дескриптор может определить любую комбинацию из [`__get__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__get__), [`__set__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__set__) и [`__delete__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__delete__). Если он не определяет [`__get__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__get__), то обращение к атрибуту вернёт сам объект дескриптора, если только в словаре экземпляра объекта нет соответствующего значения. Если дескриптор определяет [`__set__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__set__) и/или [`__delete__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__delete__), это дескриптор данных; если он не определяет ни одного из них, это дескриптор не-данных. Обычно дескрипторы данных определяют как [`__get__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__get__), так и [`__set__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__set__), в то время как дескрипторы не-данных имеют только метод [`__get__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__get__). Дескрипторы данных с определёнными [`__set__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__set__) и [`__get__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__get__) всегда переопределяют переопределение в словаре экземпляра. В отличие от них, дескрипторы не-данных могут быть переопределены экземплярами.602603Методы Python (включая [`staticmethod()`](https://python-all.ru/3.4/library/functions.html#staticmethod) и [`classmethod()`](https://python-all.ru/3.4/library/functions.html#classmethod)) реализованы как дескрипторы не-данных. Соответственно, экземпляры могут переопределять методы. Это позволяет отдельным экземплярам приобретать поведение, отличное от других экземпляров того же класса.604605Функция [`property()`](https://python-all.ru/3.4/library/functions.html#property) реализована как дескриптор данных. Соответственно, экземпляры не могут переопределить поведение свойства.606607#### 3.3.2.3. \_\_slots\_\_608609По умолчанию экземпляры классов имеют словарь для хранения атрибутов. Это расходует память для объектов с очень небольшим количеством переменных экземпляра. Расход памяти может стать критическим при создании большого числа экземпляров.610611Поведение по умолчанию можно переопределить, определив *\_\_slots\_\_* в определении класса. Объявление *\_\_slots\_\_* принимает последовательность переменных экземпляра и резервирует ровно столько памяти в каждом экземпляре, чтобы хранить значение для каждой переменной. Память экономится, поскольку *\_\_dict\_\_* не создаётся для каждого экземпляра.612613#### `object.__slots__`614615Этой переменной класса можно присвоить строку, итерируемый объект или последовательность строк с именами переменных, используемых экземплярами. *\_\_slots\_\_* резервирует место для объявленных переменных и предотвращает автоматическое создание *\_\_dict\_\_* и *\_\_weakref\_\_* для каждого экземпляра.616617##### 3.3.2.3.1. Примечания по использованию *\_\_slots\_\_*618619- При наследовании от класса без *\_\_slots\_\_* атрибут *\_\_dict\_\_* этого класса всегда будет доступен, поэтому определение *\_\_slots\_\_* в подклассе не имеет смысла.620- Без переменной *\_\_dict\_\_* экземплярам нельзя присваивать новые переменные, не перечисленные в определении *\_\_slots\_\_*. Попытка присвоить имя переменной, не входящей в список, вызывает [`AttributeError`](https://python-all.ru/3.4/library/exceptions.html#AttributeError). Если требуется динамическое присваивание новых переменных, добавьте `'__dict__'` в последовательность строк в объявлении *\_\_slots\_\_*.621- Без переменной *\_\_weakref\_\_* для каждого экземпляра классы, определяющие *\_\_slots\_\_*, не поддерживают слабые ссылки на свои экземпляры. Если требуется поддержка слабых ссылок, добавьте `'__weakref__'` в последовательность строк в объявлении *\_\_slots\_\_*.622- *\_\_slots\_\_* реализуются на уровне класса путём создания дескрипторов ([*Реализация дескрипторов*](https://python-all.ru/3.4/reference/datamodel.html#descriptors)) для каждого имени переменной. В результате атрибуты класса нельзя использовать для установки значений по умолчанию для переменных экземпляра, определённых *\_\_slots\_\_*; в противном случае атрибут класса перезаписал бы присваивание дескриптора.623- Действие объявления *\_\_slots\_\_* ограничено классом, в котором оно определено. В результате подклассы будут иметь *\_\_dict\_\_*, если только они также не определят *\_\_slots\_\_* (который должен содержать только имена *дополнительных* слотов).624- Если класс определяет слот, который также определён в базовом классе, переменная экземпляра, определённая слотом базового класса, становится недоступной (за исключением прямого получения её дескриптора из базового класса). Это делает поведение программы неопределённым. В будущем может быть добавлена проверка для предотвращения такой ситуации.625- Непустой *\_\_slots\_\_* не работает для классов, производных от встроенных типов «переменной длины», таких как [`int`](https://python-all.ru/3.4/library/functions.html#int), [`bytes`](https://python-all.ru/3.4/library/functions.html#bytes) и [`tuple`](https://python-all.ru/3.4/library/stdtypes.html#tuple).626- Любому итерируемому объекту, не являющемуся строкой, может быть присвоено *\_\_slots\_\_*. Также могут использоваться отображения; однако в будущем значениям, соответствующим каждому ключу, может быть присвоен особый смысл.627- Присваивание *\_\_class\_\_* работает, только если оба класса имеют одинаковые *\_\_slots\_\_*.628629### 3.3.3. Настройка создания классов630631По умолчанию классы создаются с помощью [`type()`](https://python-all.ru/3.4/library/functions.html#type). Тело класса выполняется в новом пространстве имён, а имя класса локально привязывается к результату `type(name, bases, namespace)`.632633Процесс создания класса можно настроить, передав ключевой аргумент `metaclass` в строке определения класса, или унаследовавшись от существующего класса, который включал такой аргумент. В следующем примере и `MyClass`, и `MySubclass` являются экземплярами `Meta`:634635```python636class Meta(type):637    pass638639class MyClass(metaclass=Meta):640    pass641642class MySubclass(MyClass):643    pass644```645646Любые другие ключевые аргументы, указанные в определении класса, передаются всем операциям метакласса, описанным ниже.647648При выполнении определения класса происходят следующие шаги:649650- Определяется подходящий метакласс.651- Подготавливается пространство имён класса.652- Выполняется тело класса.653- Создаётся объект класса.654655#### 3.3.3.1. Определение подходящего метакласса656657Подходящий метакласс для определения класса выбирается следующим образом:658659- если не указаны ни базовые классы, ни явная метакласс, то используется [`type()`](https://python-all.ru/3.4/library/functions.html#type)660- если указан явный метакласс и он *не* является экземпляром [`type()`](https://python-all.ru/3.4/library/functions.html#type), то он используется непосредственно как метакласс661- если экземпляр [`type()`](https://python-all.ru/3.4/library/functions.html#type) указан в качестве явного метакласса, или определены базовые классы, то используется наиболее производный метакласс662663Наиболее производный метакласс выбирается из явно указанного метакласса (если есть) и метаклассов (т.е. `type(cls)`) всех указанных базовых классов. Наиболее производный метакласс – это тот, который является подтипом *всех* этих кандидатов. Если ни один из кандидатов не удовлетворяет этому критерию, определение класса завершится ошибкой `TypeError`.664665#### 3.3.3.2. Подготовка пространства имён класса666667После того как подходящий метакласс определён, подготавливается пространство имён класса. Если у метакласса есть атрибут `__prepare__`, он вызывается как `namespace = metaclass.__prepare__(name, bases, **kwds)` (где дополнительные ключевые аргументы, если есть, берутся из определения класса).668669Если у метакласса нет атрибута `__prepare__`, то пространство имён класса инициализируется пустым экземпляром [`dict()`](https://python-all.ru/3.4/library/stdtypes.html#dict).670671> **См. также**672>673> **[**PEP 3115**](https://python-all.ru/3.4/reference/datamodel.html) – Метаклассы в Python 3000**674>675> Представлен хук пространства имён676>677> `__prepare__`678679#### 3.3.3.3. Выполнение тела класса680681Тело класса выполняется (приблизительно) как `exec(body, globals(), namespace)`. Ключевое отличие от обычного вызова [`exec()`](https://python-all.ru/3.4/library/functions.html#exec) в том, что лексическая область видимости позволяет телу класса (включая любые методы) ссылаться на имена из текущей и внешней областей видимости, когда определение класса происходит внутри функции.682683Однако, даже если определение класса находится внутри функции, методы, определённые внутри класса, всё равно не могут видеть имена, определённые в области видимости класса. Переменные класса должны быть доступны через первый параметр методов экземпляра или класса, и совсем недоступны из статических методов.684685#### 3.3.3.4. Создание объекта класса686687После того как пространство имён класса заполнено выполнением тела класса, объект класса создаётся вызовом `metaclass(name, bases, namespace, **kwds)` (дополнительные ключевые слова, передаваемые здесь, те же, что передавались в `__prepare__`).688689Этот объект класса будет использоваться формой [`super()`](https://python-all.ru/3.4/library/functions.html#super) без аргументов. `__class__` – это неявная ссылка на замыкание, создаваемая компилятором, если любой метод в теле класса ссылается на `__class__` или `super`. Это позволяет форме [`super()`](https://python-all.ru/3.4/library/functions.html#super) без аргументов правильно определить определяемый класс на основе лексической области видимости, в то время как класс или экземпляр, использованные для текущего вызова, определяются на основе первого аргумента, переданного методу.690691После создания объекта класса он передаётся декораторам класса,\\указанным в определении класса (если они есть), и полученный объект связывается в локальном пространстве имён как определённый класс.692693> **См. также**694>695> **[**PEP 3135**](https://python-all.ru/3.4/reference/datamodel.html) – Новый super**696>697> Описывает неявную ссылку на замыкание698>699> `__class__`700701#### 3.3.3.5. Пример метакласса702703Потенциальные возможности использования метаклассов безграничны. Некоторые идеи, которые были исследованы, включают логирование, проверку интерфейсов, автоматическое делегирование, автоматическое создание свойств, прокси, фреймворки, а также автоматическую блокировку/синхронизацию ресурсов.704705Вот пример метакласса, который использует [`collections.OrderedDict`](https://python-all.ru/3.4/library/collections.html#collections.OrderedDict) для запоминания порядка, в котором определяются переменные класса:706707```python708class OrderedClass(type):709710     @classmethod711     def __prepare__(metacls, name, bases, **kwds):712        return collections.OrderedDict()713714     def __new__(cls, name, bases, namespace, **kwds):715        result = type.__new__(cls, name, bases, dict(namespace))716        result.members = tuple(namespace)717        return result718719class A(metaclass=OrderedClass):720    def one(self): pass721    def two(self): pass722    def three(self): pass723    def four(self): pass724725>>> A.members726('__module__', 'one', 'two', 'three', 'four')727```728729Когда выполняется определение класса *A*, процесс начинается с вызова метода метакласса `__prepare__()`, который возвращает пустой [`collections.OrderedDict`](https://python-all.ru/3.4/library/collections.html#collections.OrderedDict). Это отображение записывает методы и атрибуты *A* по мере их определения в теле оператора class. После выполнения этих определений упорядоченный словарь полностью заполняется, и вызывается метод метакласса [`__new__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__new__). Этот метод создаёт новый тип и сохраняет ключи упорядоченного словаря в атрибуте с именем `members`.730731### 3.3.4. Настройка проверок экземпляров и подклассов732733Следующие методы используются для переопределения поведения по умолчанию встроенных функций [`isinstance()`](https://python-all.ru/3.4/library/functions.html#isinstance) и [`issubclass()`](https://python-all.ru/3.4/library/functions.html#issubclass).734735В частности, метакласс [`abc.ABCMeta`](https://python-all.ru/3.4/library/abc.html#abc.ABCMeta) реализует эти методы, чтобы разрешить добавление абстрактных базовых классов (ABC) в качестве «виртуальных базовых классов» к любому классу или типу (включая встроенные типы), в том числе к другим ABC.736737#### `class.__instancecheck__(self, instance)`738739Возвращает true, если *instance* должен считаться (прямым или косвенным) экземпляром *class*. Если определён, вызывается для реализации `isinstance(instance, class)`.740741#### `class.__subclasscheck__(self, subclass)`742743Возвращает true, если *subclass* должен считаться (прямым или косвенным) подклассом *class*. Если определён, вызывается для реализации `issubclass(subclass, class)`.744745Обратите внимание, что эти методы ищутся на типе (метаклассе) класса. Их нельзя определить как методы класса в самом классе. Это согласуется с поиском специальных методов, которые вызываются на экземплярах, только в данном случае экземпляром является сам класс.746747> **См. также**748>749> **[**PEP 3119**](https://python-all.ru/3.4/reference/datamodel.html) – Введение абстрактных базовых классов**750>751> Включает описание настройки поведения752>753> [`isinstance()`](https://python-all.ru/3.4/library/functions.html#isinstance)754>755> и756>757> [`issubclass()`](https://python-all.ru/3.4/library/functions.html#issubclass)758>759> через760>761> [`__instancecheck__()`](https://python-all.ru/3.4/reference/datamodel.html#class.__instancecheck__)762>763> и764>765> [`__subclasscheck__()`](https://python-all.ru/3.4/reference/datamodel.html#class.__subclasscheck__)766>767> , а также обоснование этой функциональности в контексте добавления абстрактных базовых классов (см. модуль768>769> [`abc`](https://python-all.ru/3.4/library/abc.html#module-abc)770>771> ) в язык.772773### 3.3.5. Эмуляция вызываемых объектов774775#### `object.__call__(self[, args...])`776777Вызывается, когда экземпляр «вызывается» как функция; если этот метод определён, `x(arg1, arg2, ...)` является краткой записью для `x.__call__(arg1, arg2, ...)`.778779### 3.3.6. Эмуляция типов-контейнеров780781Следующие методы могут быть определены для реализации объектов-контейнеров. Контейнеры обычно являются последовательностями (например, списки или кортежи) или отображениями (например, словари), но могут представлять и другие контейнеры. Первый набор методов используется для эмуляции последовательности или отображения; различие в том, что для последовательности допустимыми ключами должны быть целые числа *k*, для которых `0 <= k < N`, где *N* – длина последовательности, или объекты срезов, определяющие диапазон элементов. Также рекомендуется, чтобы отображения предоставляли методы `keys()`, `values()`, `items()`, `get()`, `clear()`, `setdefault()`, `pop()`, `popitem()`, `copy()` и `update()`, ведущие себя аналогично соответствующим методам стандартных словарей Python. Модуль [`collections`](https://python-all.ru/3.4/library/collections.html#module-collections) предоставляет абстрактный базовый класс [`MutableMapping`](https://python-all.ru/3.4/library/collections.abc.html#collections.abc.MutableMapping), помогающий создать эти методы из базового набора [`__getitem__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__getitem__), [`__setitem__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__setitem__), [`__delitem__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__delitem__) и `keys()`. Изменяемые последовательности должны предоставлять методы `append()`, `count()`, `index()`, `extend()`, `insert()`, `pop()`, `remove()`, `reverse()` и `sort()`, как стандартные списки Python. Наконец, типы последовательностей должны реализовывать сложение (означающее конкатенацию) и умножение (означающее повторение) через определение методов [`__add__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__add__), [`__radd__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__radd__), [`__iadd__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__iadd__), [`__mul__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__mul__), [`__rmul__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__rmul__) и [`__imul__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__imul__), описанных ниже; они не должны определять другие числовые операторы. Рекомендуется, чтобы и отображения, и последовательности реализовывали метод [`__contains__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__contains__) для эффективного использования оператора `in`; для отображений `in` должен искать по ключам отображения; для последовательностей – по значениям. Также рекомендуется, чтобы и отображения, и последовательности реализовывали метод [`__iter__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__iter__) для эффективного перебора контейнера; для отображений [`__iter__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__iter__) должен быть эквивалентен `keys()`; для последовательностей – итерироваться по значениям.782783#### `object.__len__(self)`784785Вызывается для реализации встроенной функции [`len()`](https://python-all.ru/3.4/library/functions.html#len). Должен возвращать длину объекта – целое число `>=` 0. Кроме того, объект, не определяющий метод [`__bool__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__bool__) и у которого метод [`__len__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__len__) возвращает ноль, считается ложным в логическом контексте.786787#### `object.__length_hint__(self)`788789Вызывается для реализации [`operator.length_hint()`](https://python-all.ru/3.4/library/operator.html#operator.length_hint). Должен возвращать предполагаемую длину объекта (которая может быть больше или меньше реальной длины). Длина должна быть целым числом `>=` 0. Этот метод является исключительно оптимизацией и никогда не требуется для корректности.790791Новое в версии 3.4.792793> **Примечание**794>795> Срез выполняется исключительно с помощью следующих трёх методов. Вызов вида796>797> ```python798> a[1:2] = b799> ```800>801> преобразуется в802>803> ```python804> a[slice(1, 2, None)] = b805> ```806>807> и так далее. Пропущенные элементы среза всегда заполняются `None`.808809#### `object.__getitem__(self, key)`810811Вызывается для вычисления `self[key]`. Для типов последовательностей допустимыми ключами должны быть целые числа и объекты срезов. Обратите внимание, что специальная интерпретация отрицательных индексов (если класс хочет эмулировать тип последовательности) возлагается на метод [`__getitem__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__getitem__). Если *key* имеет неподходящий тип, может быть вызвано [`TypeError`](https://python-all.ru/3.4/library/exceptions.html#TypeError); если значение выходит за пределы множества индексов последовательности (после любой специальной интерпретации отрицательных значений), должно быть вызвано [`IndexError`](https://python-all.ru/3.4/library/exceptions.html#IndexError). Для типов отображений, если *key* отсутствует (не находится в контейнере), должно быть вызвано [`KeyError`](https://python-all.ru/3.4/library/exceptions.html#KeyError).812813> **Примечание**814>815> Циклы [`for`](https://python-all.ru/3.4/reference/compound_stmts.html#for) ожидают, что для недопустимых индексов будет вызвано [`IndexError`](https://python-all.ru/3.4/library/exceptions.html#IndexError), чтобы обеспечить корректное обнаружение конца последовательности.816817#### `object.__missing__(self, key)`818819Вызывается методом [`dict`](https://python-all.ru/3.4/library/stdtypes.html#dict).[`__getitem__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__getitem__) для реализации `self[key]` в подклассах dict, когда ключ отсутствует в словаре.820821#### `object.__setitem__(self, key, value)`822823Вызывается для реализации присваивания `self[key]`. Те же замечания, что и для [`__getitem__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__getitem__). Следует реализовывать только для отображений, если объекты поддерживают изменение значений по ключам или добавление новых ключей, или для последовательностей, если элементы могут быть заменены. Для неправильных значений *key* следует вызывать те же исключения, что и для метода [`__getitem__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__getitem__).824825#### `object.__delitem__(self, key)`826827Вызывается для реализации удаления `self[key]`. Те же замечания, что и для [`__getitem__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__getitem__). Следует реализовывать только для отображений, если объекты поддерживают удаление ключей, или для последовательностей, если элементы могут быть удалены из последовательности. Для неправильных значений *key* следует вызывать те же исключения, что и для метода [`__getitem__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__getitem__).828829#### `object.__iter__(self)`830831Этот метод вызывается, когда для контейнера требуется итератор. Этот метод должен возвращать новый объект-итератор, который может перебирать все объекты в контейнере. Для отображений он должен перебирать ключи контейнера.832833Объекты-итераторы также должны реализовывать этот метод; они обязаны возвращать самих себя. Для получения дополнительной информации об объектах-итераторах см. [*Типы итераторов*](https://python-all.ru/3.4/library/stdtypes.html#typeiter).834835#### `object.__reversed__(self)`836837Вызывается (если присутствует) встроенной функцией [`reversed()`](https://python-all.ru/3.4/library/functions.html#reversed) для реализации обратной итерации. Должен возвращать новый объект-итератор, который перебирает все объекты в контейнере в обратном порядке.838839Если метод [`__reversed__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__reversed__) не предоставлен, встроенная функция [`reversed()`](https://python-all.ru/3.4/library/functions.html#reversed) вернется к использованию протокола последовательности ([`__len__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__len__) и [`__getitem__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__getitem__)). Объекты, поддерживающие протокол последовательности, должны предоставлять [`__reversed__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__reversed__) только в том случае, если они могут дать реализацию, более эффективную, чем предоставленная функцией [`reversed()`](https://python-all.ru/3.4/library/functions.html#reversed).840841Операторы проверки принадлежности ([`in`](https://python-all.ru/3.4/reference/expressions.html#in) и [`not in`](https://python-all.ru/3.4/reference/expressions.html#not-in)) обычно реализуются как итерация по последовательности. Однако объекты-контейнеры могут предоставить следующий специальный метод с более эффективной реализацией, которая также не требует, чтобы объект был последовательностью.842843#### `object.__contains__(self, item)`844845Вызывается для реализации операторов проверки вхождения. Должен возвращать true, если *элемент* находится в *self*, и false в противном случае. Для объектов-отображений следует учитывать ключи отображения, а не значения или пары ключ-значение.846847Для объектов, не определяющих [`__contains__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__contains__), проверка принадлежности сначала пытается итерироваться через [`__iter__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__iter__), затем через старый протокол итерации последовательности через [`__getitem__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__getitem__); см. [*этот раздел в справочнике по языку*](https://python-all.ru/3.4/reference/expressions.html#membership-test-details).848849### 3.3.7. Эмуляция числовых типов850851Следующие методы можно определить для эмуляции числовых объектов. Методы, соответствующие операциям, которые не поддерживаются конкретным типом реализуемого числа (например, побитовые операции для нецелых чисел), следует оставить неопределёнными.852853#### `object.__add__(self, other)`854855#### `object.__sub__(self, other)`856857#### `object.__mul__(self, other)`858859#### `object.__truediv__(self, other)`860861#### `object.__floordiv__(self, other)`862863#### `object.__mod__(self, other)`864865#### `object.__divmod__(self, other)`866867#### `object.__pow__(self, other[, modulo])`868869#### `object.__lshift__(self, other)`870871#### `object.__rshift__(self, other)`872873#### `object.__and__(self, other)`874875#### `object.__xor__(self, other)`876877#### `object.__or__(self, other)`878879Эти методы вызываются для реализации бинарных арифметических операций (`+`, `-`, `*`, `/`, `//`, `%`, [`divmod()`](https://python-all.ru/3.4/library/functions.html#divmod), [`pow()`](https://python-all.ru/3.4/library/functions.html#pow), `**`, `<<`, `>>`, `&`, `^`, `|`). Например, для вычисления выражения `x + y`, где *x* – экземпляр класса, у которого есть метод [`__add__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__add__), вызывается `x.__add__(y)`. Метод [`__divmod__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__divmod__) должен быть эквивалентен использованию [`__floordiv__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__floordiv__) и [`__mod__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__mod__); он не должен быть связан с [`__truediv__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__truediv__). Обратите внимание, что [`__pow__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__pow__) должен быть определён так, чтобы принимать необязательный третий аргумент, если требуется поддержка троичной версии встроенной функции [`pow()`](https://python-all.ru/3.4/library/functions.html#pow).880881Если один из этих методов не поддерживает операцию с переданными аргументами, он должен возвращать `NotImplemented`.882883#### `object.__radd__(self, other)`884885#### `object.__rsub__(self, other)`886887#### `object.__rmul__(self, other)`888889#### `object.__rtruediv__(self, other)`890891#### `object.__rfloordiv__(self, other)`892893#### `object.__rmod__(self, other)`894895#### `object.__rdivmod__(self, other)`896897#### `object.__rpow__(self, other)`898899#### `object.__rlshift__(self, other)`900901#### `object.__rrshift__(self, other)`902903#### `object.__rand__(self, other)`904905#### `object.__rxor__(self, other)`906907#### `object.__ror__(self, other)`908909Эти методы вызываются для реализации бинарных арифметических операций (`+`, `-`, `*`, `/`, `//`, `%`, [`divmod()`](https://python-all.ru/3.4/library/functions.html#divmod), [`pow()`](https://python-all.ru/3.4/library/functions.html#pow), `**`, `<<`, `>>`, `&`, `^`, `|`) с отражёнными (переставленными) операндами. Эти функции вызываются только в том случае, если левый операнд не поддерживает соответствующую операцию и операнды имеют разные типы. [\[2\]](https://python-all.ru/3.4/reference/datamodel.html#id5) Например, для вычисления выражения `x - y`, где *y* – экземпляр класса, у которого есть метод [`__rsub__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__rsub__), вызывается `y.__rsub__(x)`, если `x.__sub__(y)` возвращает *NotImplemented*.910911Обратите внимание, что троичная [`pow()`](https://python-all.ru/3.4/library/functions.html#pow) не будет пытаться вызывать [`__rpow__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__rpow__) (правила приведения типов стали бы слишком сложными).912913> **Примечание**914>915> Если тип правого операнда является подклассом типа левого операнда и этот подкласс предоставляет отраженный метод для операции, то этот метод будет вызван до неотраженного метода левого операнда. Это поведение позволяет подклассам переопределять операции своих предков.916917#### `object.__iadd__(self, other)`918919#### `object.__isub__(self, other)`920921#### `object.__imul__(self, other)`922923#### `object.__itruediv__(self, other)`924925#### `object.__ifloordiv__(self, other)`926927#### `object.__imod__(self, other)`928929#### `object.__ipow__(self, other[, modulo])`930931#### `object.__ilshift__(self, other)`932933#### `object.__irshift__(self, other)`934935#### `object.__iand__(self, other)`936937#### `object.__ixor__(self, other)`938939#### `object.__ior__(self, other)`940941Эти методы вызываются для реализации расширенных арифметических операторов присваивания (`+=`, `-=`, `*=`, `/=`, `//=`, `%=`, `**=`, `<<=`, `>>=`, `&=`, `^=`, `|=`). Эти методы должны пытаться выполнить операцию на месте (модифицируя *self*) и вернуть результат (который может быть, но не обязательно, *self*). Если определённый метод не определён, расширенное присваивание использует обычные методы. Например, если *x* является экземпляром класса с методом [`__iadd__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__iadd__), то `x += y` эквивалентно `x = x.__iadd__(y)` . В противном случае рассматриваются `x.__add__(y)` и `y.__radd__(x)`, как и при вычислении `x + y`. В определённых ситуациях расширенное присваивание может приводить к неожиданным ошибкам (см. [*Почему a\_tuple\[i\] += \['item'\] вызывает исключение, если обычное сложение работает?*](https://python-all.ru/3.4/faq/programming.html#faq-augmented-assignment-tuple-error)), но на самом деле это поведение является частью модели данных.942943#### `object.__neg__(self)`944945#### `object.__pos__(self)`946947#### `object.__abs__(self)`948949#### `object.__invert__(self)`950951Вызывается для реализации унарных арифметических операций (`-`, `+`, [`abs()`](https://python-all.ru/3.4/library/functions.html#abs) и `~`).952953#### `object.__complex__(self)`954955#### `object.__int__(self)`956957#### `object.__float__(self)`958959#### `object.__round__(self[, n])`960961Вызывается для реализации встроенных функций [`complex()`](https://python-all.ru/3.4/library/functions.html#complex), [`int()`](https://python-all.ru/3.4/library/functions.html#int), [`float()`](https://python-all.ru/3.4/library/functions.html#float) и [`round()`](https://python-all.ru/3.4/library/functions.html#round). Должен возвращать значение соответствующего типа.962963#### `object.__index__(self)`964965Вызывается для реализации [`operator.index()`](https://python-all.ru/3.4/library/operator.html#operator.index), а также всякий раз, когда Python необходимо без потерь преобразовать числовой объект в целое число (например, при срезах или во встроенных функциях [`bin()`](https://python-all.ru/3.4/library/functions.html#bin), [`hex()`](https://python-all.ru/3.4/library/functions.html#hex) и [`oct()`](https://python-all.ru/3.4/library/functions.html#oct)). Наличие этого метода указывает, что числовой объект является целочисленным типом. Должен возвращать целое число.966967> **Примечание**968>969> Для того чтобы целочисленный тип был согласованным, при определении [`__index__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__index__) следует также определить [`__int__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__int__), и оба должны возвращать одно и то же значение.970971### 3.3.8. Контекстные менеджеры оператора with972973*Контекстный менеджер* – это объект, который определяет контекст выполнения, устанавливаемый при выполнении оператора [`with`](https://python-all.ru/3.4/reference/compound_stmts.html#with). Контекстный менеджер управляет входом в желаемый контекст выполнения и выходом из него для исполнения блока кода. Обычно контекстные менеджеры вызываются с помощью оператора [`with`](https://python-all.ru/3.4/reference/compound_stmts.html#with) (описанного в разделе [*Оператор with*](https://python-all.ru/3.4/reference/compound_stmts.html#with)), но также могут быть использованы путём прямого вызова их методов.974975Типичные случаи использования контекстных менеджеров включают сохранение и восстановление различных видов глобального состояния, блокировку и разблокировку ресурсов, закрытие открытых файлов и т.д.976977Для получения дополнительной информации о контекстных менеджерах см. [*Типы контекстных менеджеров*](https://python-all.ru/3.4/library/stdtypes.html#typecontextmanager).978979#### `object.__enter__(self)`980981Входит в контекст выполнения, связанный с этим объектом. Оператор [`with`](https://python-all.ru/3.4/reference/compound_stmts.html#with) привяжет возвращаемое значение этого метода к цели (целям), указанной в предложении [`as`](https://python-all.ru/3.4/reference/compound_stmts.html#as) оператора (если оно есть).982983#### `object.__exit__(self, exc_type, exc_value, traceback)`984985Выходит из контекста выполнения, связанного с этим объектом. Параметры описывают исключение, которое вызвало выход из контекста. Если выход из контекста произошёл без исключения, все три аргумента будут [`None`](https://python-all.ru/3.4/library/constants.html#None).986987Если передано исключение и метод хочет подавить его (т.е. предотвратить его распространение), он должен вернуть истинное значение. В противном случае исключение будет обработано обычным образом при выходе из этого метода.988989Обратите внимание, что методы [`__exit__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__exit__) не должны повторно возбуждать переданное исключение; это обязанность вызывающего кода.990991> **См. также**992>993> **[**PEP 0343**](https://python-all.ru/3.4/reference/datamodel.html) – оператор «with»**994>995> Спецификация, предыстория и примеры для оператора996>997> [`with`](https://python-all.ru/3.4/reference/compound_stmts.html#with)998>999> в Python.10001001### 3.3.9. Поиск специальных методов10021003Для пользовательских классов неявные вызовы специальных методов гарантированно работают корректно только в том случае, если они определены в типе объекта, а не в словаре экземпляра объекта. Это поведение является причиной того, что следующий код вызывает исключение:10041005```python1006>>> class C:1007...     pass1008...1009>>> c = C()1010>>> c.__len__ = lambda: 51011>>> len(c)1012Traceback (most recent call last):1013  File "<stdin>", line 1, in <module>1014TypeError: object of type 'C' has no len()1015```10161017Причина такого поведения кроется в ряде специальных методов, таких как [`__hash__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__hash__) и [`__repr__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__repr__), которые реализованы для всех объектов, включая объекты типов. Если бы неявный поиск этих методов использовал обычный процесс поиска, он бы не срабатывал при вызове на самом объекте типа:10181019```python1020>>> 1 .__hash__() == hash(1)1021True1022>>> int.__hash__() == hash(int)1023Traceback (most recent call last):1024  File "<stdin>", line 1, in <module>1025TypeError: descriptor '__hash__' of 'int' object needs an argument1026```10271028Попытка некорректного вызова несвязанного метода класса таким образом иногда называется «путаницей метаклассов»; её можно избежать, обходя экземпляр при поиске специальных методов:10291030```python1031>>> type(1).__hash__(1) == hash(1)1032True1033>>> type(int).__hash__(int) == hash(int)1034True1035```10361037Помимо обхода атрибутов экземпляра в целях корректности, неявный поиск специальных методов обычно также обходит метод [`__getattribute__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__getattribute__) даже метакласса объекта:10381039```python1040>>> class Meta(type):1041...     def __getattribute__(*args):1042...         print("Metaclass getattribute invoked")1043...         return type.__getattribute__(*args)1044...1045>>> class C(object, metaclass=Meta):1046...     def __len__(self):1047...         return 101048...     def __getattribute__(*args):1049...         print("Class getattribute invoked")1050...         return object.__getattribute__(*args)1051...1052>>> c = C()1053>>> c.__len__()                 # Явный поиск через экземпляр1054Class getattribute invoked1055101056>>> type(c).__len__(c)          # Явный поиск через тип1057Metaclass getattribute invoked1058101059>>> len(c)                      # Неявный поиск1060101061```10621063Обход механизма [`__getattribute__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__getattribute__) таким образом даёт широкие возможности для оптимизации скорости в интерпретаторе ценой некоторой гибкости в обработке специальных методов (специальный метод *должен* быть установлен на самом объекте класса, чтобы интерпретатор мог его последовательно вызывать).10641065Сноски10661067| [\[1\]](https://python-all.ru/3.4/reference/datamodel.html#id1) | 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. |1068| --- | --- |10691070| [\[2\]](https://python-all.ru/3.4/reference/datamodel.html#id3) | Для операндов одного типа предполагается, что если неотражённый метод (например, [`__add__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__add__)) не работает, то операция не поддерживается, поэтому отражённый метод не вызывается. |1071| --- | --- |1072