В разделе Глава 28. Подробнее о программировании классов есть несколько интересных тем. В частности, подраздел Дзен пространств имен в Python: классификация имен происходит при присваивании показался довольно громоздким, зато пораздел Словари пространств имен многое прояснил в понимании пространств имен.
Однако, здесь я решил обратить внимание на средства отладки, которые использовались для пояснений к "словарям..."
In []:
#Но здесь я решил обратить внимание на приемы получения справочной информации об атрибутах классов, суперклассах...
dir(), __dict__, __class__, __base__
In []:
#Вместе с командами
!dir # или другая команда cmd (windows) после "!"
__doc__, help() # - читают """строки""" из модулей
Вместе с опциями интерфейса iPython Notebook, о которых я прочитал в у этого океанолога
In []:
"""
? - Для того, чтобы узнать, что за зверь такой наш вновь созданный объект f,
мы можем просто поставить после него знак вопроса, выполнить код и получить по нему справку.
Это сработает для любой переменной, функции, объекта или метода
?? - Если просто справка вас не устраивает и хочется копнуть поглубже, то поставьте
два вопросительных знака и ipython постарается найти для вас файл с исходным кодом,
например, функции, и ту часть в нём, где эта функция определена.
. +tab - Если мы хотим посмотреть доступные нам методы для экземпляра...,атрибута,
то достаточно поставить точку, и нажать TAB
.variables - посмотреть словарь переиеннцх (атрибутов)
"""
Получается список инструментов, которые нужно использовать для повседневного кодинга. Однако, обраитмся к примерам из книги проследим, как растут словари пространств имен, когда в игру вступают классы.
Более простой вариант этого примера мы уже видели в главе 26, но теперь мы знаем гораздо больше о методах и суперклассах, поэтому расширим его немного. Сначала определим суперкласс и подкласс с методами, которые сохраняют данные в своих экземплярах:
Более простой вариант этого примера мы уже видели в главе 26, но теперь мы знаем гораздо больше о методах и суперклассах, поэтому расширим его немного. Сначала определим суперкласс и подкласс с методами, которые сохраняют данные в своих экземплярах:
In [2]:
class super:
def hello(self):
self.data1 = 'spam'
class sub(super):
def hola(self):
self.data2 = 'eggs'
Когда мы создаем экземпляр подкласса, он начинает свое существование с пустым словарем пространства имен, но имеет ссылку на класс, стоящий выше в дереве наследования.
Фактически дерево наследования доступно в виде специальных атрибутов, которые вы можете проверить. Экземпляры обладают атрибутом class, который ссылается на класс, а классы имеют атрибут bases, который является кортежем, содержащим ссылки на суперклассы выше в дереве наследования (в версии 2.6 и 3.0 форформатs вывода и имена некоторых внутренних атрибутов немного отличаются):
Фактически дерево наследования доступно в виде специальных атрибутов, которые вы можете проверить. Экземпляры обладают атрибутом class, который ссылается на класс, а классы имеют атрибут bases, который является кортежем, содержащим ссылки на суперклассы выше в дереве наследования (в версии 2.6 и 3.0 форформатs вывода и имена некоторых внутренних атрибутов немного отличаются):
In [3]:
X = sub()
X.__dict__ # Словарь пространства имен экземпляра
Out[3]:
In [4]:
X.__class__ # Класс экземпляра
Out[4]:
In [5]:
sub.__bases__ # Суперклассы данного класса
Out[5]:
In [6]:
super.__bases__ # В Python 2.6 возвращает пустой кортеж ()
Out[6]:
Так как в классах выполняется присваивание атрибутам аргумента self, тем самым они заполняют объекты экземпляров, то есть атрибуты включаются в словари пространств имен экземпляров, а не классов.
В пространство имен объекта экземпляра записываются данные, которые могут отличаться для разных экземпляров, и аргумент self является точкой входа в это пространство имен:
В пространство имен объекта экземпляра записываются данные, которые могут отличаться для разных экземпляров, и аргумент self является точкой входа в это пространство имен:
In [7]:
Y = sub()
In [8]:
X.hello()
X.__dict__
Out[8]:
In [9]:
X.hola()
X.__dict__
Out[9]:
In [10]:
sub.__dict__.keys()
Out[10]:
In [11]:
super.__dict__.keys()
Out[11]:
In [12]:
Y.__dict__
Out[12]:
Так как атрибуты фактически являются ключами словаря, существует два способа получать и изменять их значения – по квалифицированным именам или индексированием по ключу:
In [13]:
X.data1, X.__dict__['data1']
Out[13]:
In [15]:
X.data3 = 'toast'
X.__dict__
Out[15]:
In [17]:
X.__dict__['data3'] = 'ham'
X.data3
Out[17]:
Однако такая эквивалентность применяется только к атрибутам, фактически присоединенным к экземпляру.
Так как обращение по квалифицированному имени также вызывает запуск процедуры поиска в дереве наследования, такой способ может обеспечить доступ к атрибутам, которые нельзя получить индексированием словаря.
Например, унаследованный атрибут X.hello недоступен через выражение X.dict[‘hello’].
Так как обращение по квалифицированному имени также вызывает запуск процедуры поиска в дереве наследования, такой способ может обеспечить доступ к атрибутам, которые нельзя получить индексированием словаря.
Например, унаследованный атрибут X.hello недоступен через выражение X.dict[‘hello’].
Наконец, ниже показано, что дает применение функции dir, с которой мы встречались в главах 4 и 15, к объектам классов и экземпляров.
Эта функция применяется к объектам, имеющим атрибуты: dir(object) напоминает вызов object.dict.keys().
Однако обратите внимание, что функция dir сортирует свой список и включает в него некоторые системные атрибуты; начиная с версии Python 2.2, функция dir также автоматически собирает унаследованные атрибуты, а в версии 3.0 она добавляет в перечень имена, унаследованные от класса object, который является суперклассом для всех классов
Эта функция применяется к объектам, имеющим атрибуты: dir(object) напоминает вызов object.dict.keys().
Однако обратите внимание, что функция dir сортирует свой список и включает в него некоторые системные атрибуты; начиная с версии Python 2.2, функция dir также автоматически собирает унаследованные атрибуты, а в версии 3.0 она добавляет в перечень имена, унаследованные от класса object, который является суперклассом для всех классов
In [18]:
X.__dict__, Y.__dict__
Out[18]:
In [19]:
list(X.__dict__.keys()) # Необходимо в Python 3.0
Out[19]:
In []:
# В Python 2.6
In [20]:
dir(X)
Out[20]:
In [21]:
dir(sub)
Out[21]:
In [22]:
dir(super)
Out[22]:
In []:
# В Python 3.0:
>>> dir(X)
[‘__class__’, ‘__delattr__’, ‘__dict__’, ‘__doc__’, ‘__eq__’, ‘__format__’,
...часть строк опущена...
‘data1’, ‘data2’, ‘data3’, ‘hello’, ‘hola’]
>>> dir(sub)
[‘__class__’, ‘__delattr__’, ‘__dict__’, ‘__doc__’, ‘__eq__’, ‘__format__’,
...часть строк опущена...
‘hello’, ‘hola’]
>>> dir(super)
[‘__class__’, ‘__delattr__’, ‘__dict__’, ‘__doc__’, ‘__eq__’, ‘__format__’,
...часть строк опущена...
‘hello’
]
In [23]:
help(dir)
In [25]:
dir?
In [28]:
X.__dict__??
Команда X.dict?? открывает в notebook (браузере) окно (фрейм) со справкой. Но там информации меньше, чем при ипользовании Help
Комментариев нет:
Отправить комментарий