Поиск по блогу

четверг, 16 января 2014 г.

Возможности отладки и приемы в iPython Notebok

В разделе Глава 28. Подробнее о программировании классов есть несколько интересных тем. В частности, подраздел Дзен пространств имен в Python: классификация имен происходит при присваивании показался довольно громоздким, зато пораздел Словари пространств имен многое прояснил в понимании пространств имен.
Однако, здесь я решил обратить внимание на средства отладки, которые использовались для пояснений к "словарям..."
In []:
#Но здесь я решил обратить внимание на приемы получения справочной информации об атрибутах классов, суперклассах...
dir(), __dict__, __class__, __base__
In []:
#Вместе с командами
!dir            # или другая команда cmd (windows) после "!"
__doc__, help() # - читают """строки""" из модулей
Вместе с опциями интерфейса iPython Notebook, о которых я прочитал в у этого океанолога
In []:
"""
? - Для того, чтобы узнать, что за зверь такой наш вновь созданный объект f, 
     мы можем просто поставить после него знак вопроса, выполнить код и получить по нему справку.
     Это сработает для любой переменной, функции, объекта или метода

?? - Если просто справка вас не устраивает и хочется копнуть поглубже, то поставьте 
      два вопросительных знака и ipython постарается найти для вас файл с исходным кодом, 
      например, функции, и ту часть в нём, где эта функция определена. 

. +tab - Если мы хотим посмотреть доступные нам методы для экземпляра...,атрибута, 
         то достаточно поставить точку, и нажать TAB
.variables - посмотреть словарь переиеннцх (атрибутов)
"""
Получается список инструментов, которые нужно использовать для повседневного кодинга. Однако, обраитмся к примерам из книги проследим, как растут словари пространств имен, когда в игру вступают классы.
Более простой вариант этого примера мы уже видели в главе 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 вывода и имена некоторых внутренних атрибутов немного отличаются):
In [3]:
X = sub()
X.__dict__ # Словарь пространства имен экземпляра
Out[3]:
{}
In [4]:
X.__class__ # Класс экземпляра
Out[4]:
__main__.sub
In [5]:
sub.__bases__ # Суперклассы данного класса
Out[5]:
(__main__.super,)
In [6]:
super.__bases__ # В Python 2.6 возвращает пустой кортеж ()
Out[6]:
()
Так как в классах выполняется присваивание атрибутам аргумента self, тем самым они заполняют объекты экземпляров, то есть атрибуты включаются в словари пространств имен экземпляров, а не классов.
В пространство имен объекта экземпляра записываются данные, которые могут отличаться для разных экземпляров, и аргумент self является точкой входа в это пространство имен:
In [7]:
Y = sub()
In [8]:
X.hello()
X.__dict__
Out[8]:
{'data1': 'spam'}
In [9]:
X.hola()
X.__dict__
Out[9]:
{'data1': 'spam', 'data2': 'eggs'}
In [10]:
sub.__dict__.keys()
Out[10]:
['__module__', '__doc__', 'hola']
In [11]:
super.__dict__.keys()
Out[11]:
['__module__', 'hello', '__doc__']
In [12]:
Y.__dict__
Out[12]:
{}
Так как атрибуты фактически являются ключами словаря, существует два способа получать и изменять их значения – по квалифицированным именам или индексированием по ключу:
In [13]:
X.data1, X.__dict__['data1']
Out[13]:
('spam', 'spam')
In [15]:
X.data3 = 'toast'
X.__dict__
Out[15]:
{'data1': 'spam', 'data2': 'eggs', 'data3': 'toast'}
In [17]:
X.__dict__['data3'] = 'ham'
X.data3
Out[17]:
'ham'
Однако такая эквивалентность применяется только к атрибутам, фактически присоединенным к экземпляру.
Так как обращение по квалифицированному имени также вызывает запуск процедуры поиска в дереве наследования, такой способ может обеспечить доступ к атрибутам, которые нельзя получить индексированием словаря.
Например, унаследованный атрибут X.hello недоступен через выражение X.dict[‘hello’].
Наконец, ниже показано, что дает применение функции dir, с которой мы встречались в главах 4 и 15, к объектам классов и экземпляров.
Эта функция применяется к объектам, имеющим атрибуты: dir(object) напоминает вызов object.dict.keys().
Однако обратите внимание, что функция dir сортирует свой список и включает в него некоторые системные атрибуты; начиная с версии Python 2.2, функция dir также автоматически собирает унаследованные атрибуты, а в версии 3.0 она добавляет в перечень имена, унаследованные от класса object, который является суперклассом для всех классов
In [18]:
X.__dict__, Y.__dict__
Out[18]:
({'data1': 'spam', 'data2': 'eggs', 'data3': 'ham'}, {})
In [19]:
list(X.__dict__.keys()) # Необходимо в Python 3.0
Out[19]:
['data1', 'data3', 'data2']
In []:
# В Python 2.6
In [20]:
dir(X)
Out[20]:
['__doc__', '__module__', 'data1', 'data2', 'data3', 'hello', 'hola']
In [21]:
dir(sub)
Out[21]:
['__doc__', '__module__', 'hello', 'hola']
In [22]:
dir(super)
Out[22]:
['__doc__', '__module__', 'hello']
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)
Help on built-in function dir in module __builtin__:

dir(...)
    dir([object]) -> list of strings
    
    If called without an argument, return the names in the current scope.
    Else, return an alphabetized list of names comprising (some of) the attributes
    of the given object, and of attributes reachable from it.
    If the object supplies a method named __dir__, it will be used; otherwise
    the default dir() logic is used and returns:
      for a module object: the module's attributes.
      for a class object:  its attributes, and recursively the attributes
        of its bases.
      for any other object: its attributes, its class's attributes, and
        recursively the attributes of its class's base classes.


In [25]:
dir?
In [28]:
X.__dict__??
Команда X.dict?? открывает в notebook (браузере) окно (фрейм) со справкой. Но там информации меньше, чем при ипользовании Help

Комментариев нет:

Отправить комментарий