The Python Language Reference / Справочник по языку Python: 3. Модель данных

← →
Английский оригинал Перевод на русский

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

object.__dir__(self)

Hittih 19.09.10 в 03:56

0

Вызывается, когда вызывается «dir()» с аргументом «object» . Должен возвращаться список.

Hittih 19.09.10 в 03:56

0

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

Hittih 19.09.10 в 04:28

0

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

Hittih 19.09.10 в 07:17

0

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

Hittih 19.09.10 в 07:34

0

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

Hittih 01.12.11 в 04:48

0

object.__get__(self, instance, owner)

Hittih 19.09.10 в 07:38

0

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

Hittih 19.09.10 в 08:18

0

object.__set__(self, instance, value)

Hittih 19.09.10 в 08:20

0

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

Hittih 19.09.10 в 08:27

0

object.__delete__(self, instance)

Hittih 19.09.10 в 08:27

0

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

Hittih 19.09.10 в 08:29

0

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

Hittih 24.09.10 в 12:37

0

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

Hittih 24.09.10 в 12:53

0

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

Hittih 24.09.10 в 13:27

0

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

Hittih 03.12.11 в 09:11

0

Обычно эффект доступа к атрибутам заключается в чтении, записи или удалении их из словаря объекта. Например, поиск «a.x» происходит в такой последовательности : «a.__dict__['x']» , затем «type(a).__dict__['x']» и далее в базовых классах класса «type(a)» , исключая метаклассы.

Hittih 24.09.10 в 13:50

0

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

Hittih 24.09.10 в 14:03

0

Отправной точкой для вызова дескриптора является значение «<code>a.x</code>» : то как собираются аргументы для этого вызова – зависит от «<code>a</code>» :

Hittih 19.12.11 в 15:00

0

Прямой вызов

Hittih 24.09.10 в 14:13

0

Простейшим и наименее обычным является прямой вызов пользовательским кодом дескрипторного метода : «x.__get__(a)» .

Hittih 24.09.10 в 14:21

0

Связывание (подстановка) через экземпляр

Hittih 24.09.10 в 14:34

0

При связывании через объект-экземпляр «a» : «a.x» преобразуется в вызов «type(a).__dict__['x'].__get__(a, type(a))» .

Hittih 24.09.10 в 14:37

0

Связывание (подстановка) через класс

Hittih 24.09.10 в 14:37

0

При связывании через класс «A» : «A.x» преобразуется в вызов «A.__dict__['x'].__get__(None, A)» .

Hittih 24.09.10 в 14:38

0

Связывание (подстановка) через базовый класс

Hittih 19.12.11 в 15:05

0

Если «<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

0

Например привязки, приоритет описания обращения зависит от того, какие описательские
методы определены. Как правило, описания данных определяют как get__ __ () и __ set__ (), в то время как среди нефактических описаний данных есть только get__ __ () метод. Описания данных всегда отменяют переопределения в словаре экземпляра. И наоборот, нефактические описания данных могут быть переопределены с помощью экземпляров.

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

alvadia3 09.09.13 в 10:57

0

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

alvadia3 09.09.13 в 10:41

0

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

alvadia3 09.09.13 в 10:32

0

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

Hittih 03.10.10 в 16:44

0

Это стандартное поведение можно отменить, определив «__slots__» в определении класса. «__slots__» получает последовательность переменных экземпляра и резервирует в каждом экземпляре только необходимое для хранения значений всех его переменных количество места. Место экономится, поскольку не создаётся «__dict__» для каждого экземпляра.

Hittih 03.10.10 в 16:59

0

object.__slots__

Hittih 03.10.10 в 17:02

0

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

Hittih 03.10.10 в 17:13

0

3.3.2.3.1. Замечания по использованию «__slots__»
При наследовании от класса без «__slots__», атрибут «__dict__» этого класса будет всегда доступным, поэтому определение «__slots__» в подклассах бесполезно.

Hittih 03.10.10 в 17:20

0

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

RedFox 02.11.10 в 09:22

0

Без переменной «<code>__weakref__</code>» у каждого экземпляра – классы, в которых определён «<code>__slots__</code>» – не поддерживают «слабые» ссылки на свои экземпляры. Если поддержка слабых ссылок нужна, то к последовательности строк в объявлении «<code>__slots__</code>» добавьте «<code>”__weakref__”</code>» .

Hittih 09.01.11 в 19:18

0

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

Hittih 09.01.11 в 19:41

0

Эффект объявления «<code>__slots__</code>» распространяется только на тот класс, в котором этот атрибут определён. Таким образом : подклассы будут иметь атрибут «<code>__dict__</code>» , если сами также не определят «<code>__slots__</code>» (который должен содержать имена только дополнительных “слотов” ) .

Hittih 01.02.11 в 07:52

0

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

Hittih 01.02.11 в 08:19

0

Непустой атрибут «<code>__slots__</code>» не действует для классов, произведённых от встроенных типов “переменной длинны” , таких как «<code>int</code>» , «<code>str</code>» и «<code>tuple</code>» .

Hittih 01.02.11 в 08:36

0

Любой перебираемый (“итерируемый”) объект, кроме текста – может быть назначен атрибуту «<code>__slots__</code>» . Отображения тоже могут быть использованы, однако, в будущем им может быть придан специальный смысл.

Hittih 01.02.11 в 09:06

0

Назначение атрибуту «<code>__class__</code>» работает, только если оба класса имеют один и тот же «<code>__slots__</code>» .

Hittih 01.02.11 в 09:15

0

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

Hittih 04.11.10 в 00:01

0

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

Hittih 04.11.10 в 00:22

0

Модифицируя словарь данного класса перед тем, как данный класс будет создан.

Hittih 04.11.10 в 00:41

0

Возвращая экземпляр другого класса, по сути исполняя роль функций-фабрик.

Hittih 04.11.10 в 00:48

0

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

Hittih 04.11.10 в 01:13

0

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

Hittih 04.11.10 в 15:36

0

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

Hittih 04.11.10 в 16:08

0

Если у данного класса есть атрибут «<code>__prepare__()</code>» (обычно реализованный как класс или статический метод) , то он вызывается с именем данного класса и с кортежем его базовых классов в качестве аргументов – до исполнения (интерпретации) “тела” данного класса. Результатом должен быть объект, поддерживающий интерфейс отображения, который будет содержать область имён данного класса. По-умолчанию – это простой словарь. Это может использоваться, например, для запоминания (в возвращаемом упорядоченном словаре) того порядка, в котором атрибуты данного класса были объявлены.

Hittih 01.02.11 в 11:17

0

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

Hittih 04.11.10 в 16:53

0

Если аргумент под именем «metaclass» передан с базовыми классами, то используется он.

Hittih 04.11.10 в 16:58

0

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

Hittih 04.11.10 в 17:08

0

Иначе – используется метакласс по умолчанию («type») .

Hittih 04.11.10 в 17:10

0

Возможные применения для метаклассов неограничены. Наиболее разработаны следующие : логирование, проверка интерфейса, автоматическое делегирование, автоматическое создание свойств, посредники, среды исполнения, и т. д. .

Hittih 04.11.10 в 17:27

0
Минутку...

← Предыдущая страница

Следующая страница →