Продолжение топика Альтернативное описание паттернов проектирования
Iterator — представляет собой объект, позволяющий получить последовательный доступ к элементам объекта-агрегата без использования описаний каждого из объектов, входящий в состав агрегации.
На нашем, осмысленном примере это означает, что мы вместо специализированной функции printAll класса FileSystem, которая распечатывала содержимое файловой системы, подставим более универсальную iteritems, возвращающую итератор.
Для удобства сравнения кода с базовым примером, он слева, добавлена картинка аля — diff.
Сам код примера.
# -*- coding: utf-8 -*-
fileSystem = None
class File:
def __init__(self, size):
self.size = size
self.ind = fileSystem.create(self)
self.parent = None
def name(self):
if not self.parent:
return ""
else:
return self.parent.getName(self.ind)
class Dir:
def __init__(self):
self.ind = fileSystem.create(self)
self.parent = None
self.container = {}
def getName(self, ind):
return self.name() + self.container[ind]
def name(self):
if not self.parent:
return ""
else:
return self.parent.getName(self.ind) + "/"
def size(self):
return len(self.container)
def add(self, name, file):
file.parent = self
self.container[file.ind] = name
class Root(Dir):
def __init__(self):
Dir.__init__(self)
def name(self):
return "/"
class Link:
def __init__(self, link):
self.link = link
self.ind = fileSystem.create(self)
self.parent = None
def name(self):
if not self.parent:
return " -> " + self.link.name()
else:
return self.parent.getName(self.ind) + " -> " + self.link.name()
def size(self):
return 8
class FileSystem:
def __init__(self):
self.container = {}
def create(self, file):
ind = hash(file)
self.container[ind] = file
return ind
def find(self, name):
for value in self.container.itervalues():
if value.name() == name:
return value
return None
def iteritems(self):
return self.container.itervalues()
if __name__ == "__main__":
fileSystem = FileSystem()
root = Root()
etc = Dir()
root.add("etc", etc)
home = Dir()
root.add("home", home)
user = Dir()
home.add("user", user)
user.add("readme.txt", File(1177))
user.add(".etc", Link(etc))
for value in fileSystem.iteritems():
if isinstance(value, File):
print "file: %8d %s" % (value.size, value.name())
elif isinstance(value, Dir):
print " dir: %8d %s" % (value.size(), value.name())
elif isinstance(value, Link):
print "link: %8d %s" % (value.size(), value.name())
print "find('/home/user')=", fileSystem.find("/home/user")
print "find('/home/user/')=", fileSystem.find("/home/user/")
В результате выполнения кода имеем повтор результата базового примера с точностью до перестановки строк вывода:
dir: 2 /home/user/
file: 1177 /home/user/readme.txt
link: 8 /home/user/.etc -> /etc/
dir: 2 /
dir: 0 /etc/
dir: 1 /home/
find('/home/user')= None
find('/home/user/')= <__main__.Dir instance at 0x7f74ee8c3638>
Автор: bya