Опубликован: 22.12.2005 | Уровень: для всех | Доступ: платный
Лекция 4:

Объектно-ориентированное программирование

Агрегация

Контейнеры

Под контейнером обычно понимают объект, основным назначением которого является хранение и обеспечение доступа к другим объектам. Контейнеры реализуют отношение "HAS-A" ("ИМЕЕТ") между объектами. Встроенные типы, список и словарь -- яркие примеры контейнеров. Можно построить собственные типы контейнеров, которые будут иметь свою логику доступа к хранимым объектам. В контейнере хранятся не сами объекты, а ссылки на них.

Для практических нужд в Python обычно хватает встроенных контейнеров (словаря и списка), но если это необходимо, можно создать и другие. Ниже приведен класс Стек, реализованный на базе списка:

class Stack:
  def __init__(self):
    """Инициализация стека"""
    self._stack = []
  def top(self):
    """Возвратить вершину стека (не снимая)"""
    return self._stack[-1]
  def pop(self):
    """Снять со стека элемент"""
    return self._stack.pop()
  def push(self, x):
    """Поместить элемент на стек"""
    self._stack.append(x)
  def __len__(self):
    """Количество элементов в стеке"""
    return len(self._stack)
  def __str__(self):
    """Представление в виде строки"""
    return " : ".join(["%s" % e for e in self._stack])

Использование:

>>> s = Stack()
>>> s.push(1)
>>> s.push(2)
>>> s.push("abc")
>>> print s.pop()
abc
>>> print len(s)
2
>>> print s
1 : 2

Таким образом, контейнеры позволяют управлять набором (любых) других объектов в соответствии со структурой их хранения, не вмешиваясь во внутренние дела объектов. Узнав интерфейс класса Stack, можно и не догадаться, что он реализован на основе списка, и каким именно образом он реализован с помощью него. Но для использования стека это не важно.

Примечание:

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

Итераторы

Итераторы - это объекты, которые предоставляют последовательный доступ к элементам контейнера (или генерируемым "на лету" объектам). Итератор позволяет перебирать элементы, абстрагируясь от реализации того контейнера, откуда он их берет (если этот контейнер вообще есть).

В следующем примере приведен итератор, выдающий значения из списка по принципу "считалочки" по N:

class Zahlreim:
  def __init__(self, lst, n):
    self.n = n
    self.lst = lst
    self.current = 0
  def __iter__(self): 
    return self
  def next(self):
    if self.lst:
      self.current = (self.current + self.n - 1) % len(self.lst) 
      return self.lst.pop(self.current)
    else: 
      raise StopIteration

print range(1, 11)
for i in Zahlreim(range(1, 11), 5):
  print i,

Программа выдаст

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
5 10 6 2 9 8 1 4 7 3

В этой программе делегировано управление доступом к элементам списка (или любого другого контейнера, имеющего метод pop(n) для взятия и удаления n -го элемента) классу-итератору. Итератор должен иметь метод next() и возбуждать исключение StopIteration по завершении итераций. Кроме того, метод __iter__() должен выдавать итератор по экземпляру класса (в данном случае итератор - он сам ( self )).

В настоящее время итераторы приобретают все большее значение, и о них много говорилось в лекции по функциональному программированию.

Сергей Крупко
Сергей Крупко

Добрый день.

Я сейчас прохожу курс  повышения квалификации  - "Профессиональное веб-программирование". Мне нужно получить диплом по этому курсу. Я так полагаю нужно его оплатить чтобы получить диплом о повышении квалификации. Как мне оплатить этот курс?

 

Павел Ялганов
Павел Ялганов

Скажите экзамен тоже будет ввиде теста? или там будет какое то практическое интересное задание?

Мария Кравцова
Мария Кравцова
Россия, Сочи, РГПУ им. А.И.Герцена, 1997
Екатерина Архангельская
Екатерина Архангельская
Россия, СПбГУАП