The Python Language Reference / Справочник по языку Python: 3. Модель данных
| Английский оригинал | Перевод на русский | |
|---|---|---|
Сожалеем, но текст оригинала доступен только зарегистрированным пользователям. |
object.__dir__(self) Hittih 19.09.10 в 03:56 |
|
|
Вызывается, когда вызывается «dir()» с аргументом «object» . Должен возвращаться список. Hittih 19.09.10 в 03:56 |
||
|
3.3.2.1. Реализация дескрипторов Hittih 19.09.10 в 04:28 3.3.2.1. Реализация дескрипторов Hittih 19.09.10 в 07:17 3.3.2.1. Реализация дескрипторов Hittih 19.09.10 в 07:34 3.3.2.1. Реализация дескрипторов Hittih 01.12.11 в 04:48 |
||
|
object.__get__(self, instance, owner) Hittih 19.09.10 в 07:38 |
||
|
Вызывается для получения «данного атрибута» класса-владельца (доступ к атрибуту класса) или экземпляра класса-владельца (доступ к атрибуту экземпляра) . Аргумент «owner» всегда – класс-владелец, а аргумент «instance» – это тот экземпляр, через который «данный атрибут» был получен или «None» , когда «данный атрибут» был получен через «владельца» . Этот метод должен возвращать значение «данного атрибута» (вычисленное) , или инициировать исключение «AttributeError» . Hittih 19.09.10 в 08:18 |
||
|
object.__set__(self, instance, value) Hittih 19.09.10 в 08:20 |
||
|
Вызывается для установки (записи) значения «value» для «данного атрибута» в экземпляре «instance» класса-владельца. Hittih 19.09.10 в 08:27 |
||
|
object.__delete__(self, instance) Hittih 19.09.10 в 08:27 |
||
|
Вызывается для удаления «данного атрибута» в экземпляре «instance» класса-владельца. Hittih 19.09.10 в 08:29 |
||
|
3.3.2.2. Вызов дескрипторов Hittih 24.09.10 в 12:37 3.3.2.2. Вызов дескрипторов Hittih 24.09.10 в 12:53 3.3.2.2. Вызов дескрипторов Hittih 24.09.10 в 13:27 3.3.2.2. Вызов дескрипторов Hittih 03.12.11 в 09:11 |
||
|
Обычно эффект доступа к атрибутам заключается в чтении, записи или удалении их из словаря объекта. Например, поиск «a.x» происходит в такой последовательности : «a.__dict__['x']» , затем «type(a).__dict__['x']» и далее в базовых классах класса «type(a)» , исключая метаклассы. Hittih 24.09.10 в 13:50 |
||
|
Но, если значением искомого атрибута является объект, в котором определён один из дескрипторных методов, то Питон может обойти обычное поведение и вызвать вместо этого дескрипторный метод. На каком этапе последовательности поиска атрибута это произойдёт – зависит от того, какие дескрипторные методы были определены, и как они были вызваны. Hittih 24.09.10 в 14:03 |
||
|
Отправной точкой для вызова дескриптора является значение «<code>a.x</code>» : то как собираются аргументы для этого вызова – зависит от «<code>a</code>» : Hittih 19.12.11 в 15:00 |
||
|
Прямой вызов Hittih 24.09.10 в 14:13 |
||
|
Простейшим и наименее обычным является прямой вызов пользовательским кодом дескрипторного метода : «x.__get__(a)» . Hittih 24.09.10 в 14:21 |
||
|
Связывание (подстановка) через экземпляр Hittih 24.09.10 в 14:34 |
||
|
При связывании через объект-экземпляр «a» : «a.x» преобразуется в вызов «type(a).__dict__['x'].__get__(a, type(a))» . Hittih 24.09.10 в 14:37 |
||
|
Связывание (подстановка) через класс Hittih 24.09.10 в 14:37 |
||
|
При связывании через класс «A» : «A.x» преобразуется в вызов «A.__dict__['x'].__get__(None, A)» . Hittih 24.09.10 в 14:38 |
||
|
Связывание (подстановка) через базовый класс Hittih 19.12.11 в 15:05 |
||
|
Если «<code>a</code>» является экземпляром “надкласса” , то при связывании через «<code>super(B, obj).m()</code>» используется «<code>obj.__class__.__mro__</code>» чтобы найти такой класс «<code>A</code>» , который является непосредственным базовым классом для «<code>B</code>», и затем вызывается «<code>A.__dict__['m'].__get__(obj, A)</code>» . Hittih 19.12.11 в 15:31 |
||
|
Например привязки, приоритет описания обращения зависит от того, какие описательские alvadia3 09.09.13 в 10:57 |
||
|
Методы Python (в том числе staticmethod() и classmethod() ) реализованы в виде нефактических описаний. Соответственно, экземпляры могут переопределять и аннулировать методы. Это позволяет отдельным экземплярам приобрести свойства, которые отличаются от свойств других экземпляров того же класса. alvadia3 09.09.13 в 10:41 |
||
|
Функция присваивания реализована в виде описания данных. Соответственно, экземпляры не могут переопределять свойства наследования. alvadia3 09.09.13 в 10:32 |
||
|
3.3.2.3. «__slots__» Hittih 03.10.10 в 16:44 |
||
|
Это стандартное поведение можно отменить, определив «__slots__» в определении класса. «__slots__» получает последовательность переменных экземпляра и резервирует в каждом экземпляре только необходимое для хранения значений всех его переменных количество места. Место экономится, поскольку не создаётся «__dict__» для каждого экземпляра. Hittih 03.10.10 в 16:59 |
||
|
object.__slots__ Hittih 03.10.10 в 17:02 |
||
|
Этой переменной класса можно назначить строку, итерируемый объект или последовательность строк с именами переменных, используемых экземплярами. В случае объявления его в классе, «__slots__» резервирует место для объявленных переменных и отменяет автоматическое создание «__dict__» и «__weakref__» для каждого экземпляра. Hittih 03.10.10 в 17:13 |
||
|
3.3.2.3.1. Замечания по использованию «__slots__» Hittih 03.10.10 в 17:20 |
||
|
Без переменной __dict__ экземплярам не могут быть назначены новые переменные, не перечисленные в определении __slots__. Попытки назначений не перечисленных имен переменных вызывают ошибку AttributeError. Если желательно динамическое назначение новых переменных, добавьте '__dict__' в последовательность строк в определении __slots__. RedFox 02.11.10 в 09:22 |
||
|
Без переменной «<code>__weakref__</code>» у каждого экземпляра – классы, в которых определён «<code>__slots__</code>» – не поддерживают «слабые» ссылки на свои экземпляры. Если поддержка слабых ссылок нужна, то к последовательности строк в объявлении «<code>__slots__</code>» добавьте «<code>”__weakref__”</code>» . Hittih 09.01.11 в 19:18 |
||
|
«<code>__slots__</code>» реализованы на уровне соответствующего класса посредством создания дескрипторов (смотрите «Реализация дескрипторов») для каждого имени переменной. В результате атрибуты класса не могут быть использованы для установки значений по-умолчанию для переменных у экземпляров, определённых посредством «<code>__slots__</code>» – иначе атрибуты этих классов могли бы переписать назначение этих дескрипторов. Hittih 09.01.11 в 19:41 |
||
|
Эффект объявления «<code>__slots__</code>» распространяется только на тот класс, в котором этот атрибут определён. Таким образом : подклассы будут иметь атрибут «<code>__dict__</code>» , если сами также не определят «<code>__slots__</code>» (который должен содержать имена только дополнительных “слотов” ) . Hittih 01.02.11 в 07:52 |
||
|
Если класс определяет “слот” , который определён и в базовом классе, то та переменная экземпляра, которая определена “слотом” базового класса, будет недоступна (за исключением явного получения дескриптора через базовый класс) . Это делает неопределённым значение программы. В будущем для предотвращения этого может быть добавлена какая-либо проверка. Hittih 01.02.11 в 08:19 |
||
|
Непустой атрибут «<code>__slots__</code>» не действует для классов, произведённых от встроенных типов “переменной длинны” , таких как «<code>int</code>» , «<code>str</code>» и «<code>tuple</code>» . Hittih 01.02.11 в 08:36 |
||
|
Любой перебираемый (“итерируемый”) объект, кроме текста – может быть назначен атрибуту «<code>__slots__</code>» . Отображения тоже могут быть использованы, однако, в будущем им может быть придан специальный смысл. Hittih 01.02.11 в 09:06 |
||
|
Назначение атрибуту «<code>__class__</code>» работает, только если оба класса имеют один и тот же «<code>__slots__</code>» . Hittih 01.02.11 в 09:15 |
||
|
3.3.3. Управление созданием классов Hittih 04.11.10 в 00:01 |
||
|
Когда описание данного класса считывается, если передан исполнимый аргумент под ключевым словом «metaclass» после базовых классов в определении класса, то этот исполнимый объект будет вызван вместо «type()» . Если переданы и другие именованные аргументы, то они также будут переданы этому метаклассу. Это позволяет писать классы или функции, которые отслеживают или изменяют процесс создания класса : Hittih 04.11.10 в 00:22 |
||
|
Модифицируя словарь данного класса перед тем, как данный класс будет создан. Hittih 04.11.10 в 00:41 |
||
|
Возвращая экземпляр другого класса, по сути исполняя роль функций-фабрик. Hittih 04.11.10 в 00:48 |
||
|
Эти шаги должны быть исполнены в методе «__new__()» данного метакласса – затем из этого метода может быть вызван «type.__new__()» для создания класса с другими свойствами. Следующий пример добавляет новый элемент к словарю данного класса перед созданием данного класса : Hittih 04.11.10 в 01:13 |
||
|
<code>class metacls(type): Hittih 04.11.10 в 15:36 |
||
|
Конечно, вы можете ещё и переопределять другие методы класса (или добавлять новые) . Например, определение метода «__call__()» позволяет настроить то, как ведёт себя данный класс при вызове, например, чтобы он не каждый раз создавал новый экземпляр. Hittih 04.11.10 в 16:08 |
||
|
Если у данного класса есть атрибут «<code>__prepare__()</code>» (обычно реализованный как класс или статический метод) , то он вызывается с именем данного класса и с кортежем его базовых классов в качестве аргументов – до исполнения (интерпретации) “тела” данного класса. Результатом должен быть объект, поддерживающий интерфейс отображения, который будет содержать область имён данного класса. По-умолчанию – это простой словарь. Это может использоваться, например, для запоминания (в возвращаемом упорядоченном словаре) того порядка, в котором атрибуты данного класса были объявлены. Hittih 01.02.11 в 11:17 |
||
|
Соответствующий метакласс определяется следующей последовательностью правил : Hittih 04.11.10 в 16:53 |
||
|
Если аргумент под именем «metaclass» передан с базовыми классами, то используется он. Hittih 04.11.10 в 16:58 |
||
|
Иначе, если есть хотя бы один базовый класс, то используются его метаклассы. Hittih 04.11.10 в 17:08 |
||
|
Иначе – используется метакласс по умолчанию («type») . Hittih 04.11.10 в 17:10 |
||
|
Возможные применения для метаклассов неограничены. Наиболее разработаны следующие : логирование, проверка интерфейса, автоматическое делегирование, автоматическое создание свойств, посредники, среды исполнения, и т. д. . Hittih 04.11.10 в 17:27 |
