Чтение онлайн

на главную

Жанры

Язык программирования Python
Шрифт:

Итераторы

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

В следующем примере приведен итератор, выдающий значения из списка по принципу «считалочки» по 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)).

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

Ассоциация

Если в случае агрегации имеется довольно четкое отношение «ИМЕЕТ» (HAS–A) или «СОДЕРЖИТСЯ–В», которое даже отражено в синтаксисе Python:

Листинг

lst = [1, 2, 3]

if 1 in lst:

то в случае ассоциации ссылка на экземпляр другого класса используется без отношения включения одного в другой или принадлежности. О таком отношении между классами говорят как об отношении USE–A («ИСПОЛЬЗУЕТ»). Это достаточно общее отношение зависимости между классами.

В языке Python границы между агрегацией и ассоциацией несколько размыты, так как объекты при агрегации обычно не хранятся в области памяти, выделенной под контейнер (хранятся только ссылки).

Объекты могут также ссылаться друг на друга. В этом случае возникают циклические ссылки, которые при неаккуратном использовании могут привести (в старых версиях Python) к утечкам памяти. В новых версиях Python для циклических ссылок работает сборщик мусора.

Разумеется, при «чистой» агрегации циклических ссылок не возникает.

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

Слабые ссылки

Для обеспечения ассоциаций объектов без свойственных ссылкам проблем с возможностью образования циклических ссылок, в Python для сложных структур данных и других видов использования, при которых ссылки не должны мешать удалению объекта, предлагается механизм слабых ссылок. Такая ссылка не учитывается при подсчете ссылок на объект, а значит, объект удаляется с исчезновением последней «сильной» ссылки.

Для работы со слабыми ссылками применяется модуль weakref. Основные принципы

его работы станут понятны из следующего примера:

Листинг

>>> import weakref

>>>

>>> class MyClass(object):

… def __str__(self):

… return «MyClass»

>>>

>>> s = MyClass # создается экземпляр класса

>>> print s

MyClass

>>> s1 = weakref.proxy(s) # создается прокси–объект

>>> print s1 # прокси–объект работает как исходный

MyClass

>>> ss = weakref.ref(s) # создается слабая ссылка на него

>>> print ss # вызовом ссылки получается исходный объект

MyClass

>>> del s # удаляется единственная сильная ссылка на объект

>>> print ss # теперь исходного объекта не существует

None

>>> print s1

Traceback (most recent call last):

File "<stdin>", line 1, in ?

ReferenceError: weakly–referenced object no longer exists

К сожалению, поведение прокси–объекта не совсем такое, как у исходного: он не может быть ключом словаря, так как является нехэшируемым.

Статический метод

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

Листинг

class A(object):

def name:

return A.__name__

name = staticmethod(name)

print A.name

a = A

print a.name

Статическому методу не передается параметр с экземпляром класса. Он ему попросту не нужен.

В Python 2.4 для применения описателей (descriptors) был придуман новый синтаксис — декораторы:

Листинг

class A(object):

@staticmethod

def name:

return A.__name__

Смысл декоратора в том, что он «пропускает» определяемую функцию (или метод) через заданную в нем функцию. Теперь писать name три раза не потребовалось. Декораторов может быть несколько, и применяются они в обратном порядке.

Метод класса

Если статический метод имеет свои аналоги в C++ и Java, то метод класса основан на том, что в Python классы являются объектами. В отличие от статического метода, в метод класса первым параметром передается объект–класс. Вместо self для подчеркивания принадлежности метода к методам класса принято использовать cls.

Пример использования метода класса можно найти в модуле tree пакета nltk (Natural Language ToolKit, набор инструментов для естественного языка). Ниже приведен лишь фрагмент определения класса Tree (базового класса для других подклассов). Метод convert класса Tree определяет процедуру преобразования дерева одного типа в дерево другого типа. Эта процедура абстрагируется от деталей реализации конкретных типов, описывая обобщенный алгоритм преобразования:

Поделиться:
Популярные книги

Тринадцатый XI

NikL
11. Видящий смерть
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Тринадцатый XI

Хозяйка забытой усадьбы

Воронцова Александра
5. Королевская охота
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Хозяйка забытой усадьбы

Виконт. Книга 3. Знамена Легиона

Юллем Евгений
3. Псевдоним `Испанец`
Фантастика:
фэнтези
попаданцы
аниме
7.00
рейтинг книги
Виконт. Книга 3. Знамена Легиона

Шайтан Иван 6

Тен Эдуард
6. Шайтан Иван
Фантастика:
попаданцы
альтернативная история
историческое фэнтези
7.00
рейтинг книги
Шайтан Иван 6

Правильный лекарь. Том 12

Измайлов Сергей
12. Неправильный лекарь
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Правильный лекарь. Том 12

Последний рейд

Сай Ярослав
5. Медорфенов
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Последний рейд

Черный маг императора 3

Герда Александр
3. Черный маг императора
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Черный маг императора 3

Лихие. Авторитет

Вязовский Алексей
3. Бригадир
Фантастика:
альтернативная история
попаданцы
5.00
рейтинг книги
Лихие. Авторитет

Потомок бога

Решетов Евгений Валерьевич
1. Локки
Фантастика:
попаданцы
альтернативная история
аниме
сказочная фантастика
5.00
рейтинг книги
Потомок бога

Неудержимый. Книга XXX

Боярский Андрей
30. Неудержимый
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Неудержимый. Книга XXX

Наследие Маозари 5

Панежин Евгений
5. Наследие Маозари
Фантастика:
фэнтези
юмористическое фэнтези
5.00
рейтинг книги
Наследие Маозари 5

Газлайтер. Том 3

Володин Григорий
3. История Телепата
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Газлайтер. Том 3

Бастард Императора. Том 5

Орлов Андрей Юрьевич
5. Бастард Императора
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Бастард Императора. Том 5

Неудержимый. Книга XIX

Боярский Андрей
19. Неудержимый
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Неудержимый. Книга XIX