Основы объектно-ориентированного программирования [Ю. А. Блинков] (pdf) читать постранично, страница - 4

Книга в формате pdf! Изображения и текст могут не отображаться!


 [Настройки текста]  [Cбросить фильтры]

могут быть описаны кратко. TelephoneType определяется
своим названием. TelephoneTypes представляет собой множество из объектов класса TelephoneType.
Класс Telephone состоит из номера и его типа. Телефоны содержаться в множестве задаваемым
классом Telephones. Телефонный справочник содержит TelephoneRecord ссылающийся на телефоны
и подразделения.
Рассмотрим реализацию телефонного справочника . Для усвоения использованного ниже материала необходимо усвоить 1-4 лекции и часть лекции 7 курса “Учебный курс - Язык программирования Python” [3] Сузи Романа Арвиевича.
1 # -*- coding: utf-8 -*2
3 """

4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

Телефонная книга организации
"""
import itertools
class Collaborator:
"""
Сотрудник
"""
def __init__(self, code, family, name, patronym):
self.code = code
self.family = family
self.name = name
self.patronym = patronym
def __hash__(self):
return hash(self.code)
def __eq__(self, other):
return self.code == other.code

Строка 1 определяет используемую кодировку. Затем, нам строках 3-5, определяем документацию
нашей программы. На 7 строке импортируем модуль itertools для организации итераторов для обхода
подразделения по его сотрудникам и по его собственным подразделениям. Далее следует описание
класса Collaborator. При вычисление хэш используется стандартная hash функция языка Python.
25 class Subdivision:

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

"""
Подразделение
"""
def __init__(self, name):
self.name = name
self.collaborators = set()
self.subdivisions = set()
def __hash__(self):
return hash(self.name)
def __eq__(self, other):
return self.name == other.name
def __iter__(self):
i = iter(self.collaborators)
for s in self.subdivisions:
i = itertools.chain(i, iter(s))
return i
def add(self, collaborator):
assert collaborator not in self
self.collaborators.add(collaborator)
def addSubdivision(self, subdivision):
assert subdivision not in self.subdivisions
assert not set(self).intersection(set(subdivision))

53
54
55
56
57
58
59

self.subdivisions.add(subdivision)
def iterSubdivision(self):
i = iter(self.subdivisions)
for s in self.subdivisions:
i = itertools.chain(i, s.iterSubdivision())
return i

В Subdivision для организации итераторов __iter__ и iterSubdivision используется так называемое зацепление итераторов. Операция add на строчке 47 запрещает добавлять сотрудника к подразделению
если он есть в нем или в его собственном подразделении. Это достигается за счет переопределения стандартного метода __iter__ для контейнера языка Python. Строчка 51 запрещает добавлять
подразделение если там оно уже есть, а строчка 52 если в нем есть хотя бы один сотрудник уже
имеющиеся в нашем подразделении.
61 class TelephoneType:
62
"""
63
Тип телефона
64
"""
65
def __init__(self, name):
66
self.name = name
67
68
def __hash__(self):
69
return hash(self.name)
70
71
def __eq__(self, other):
72
return self.name == other.name

Тип телефона определяется его именем.
74 class TelephoneTypes(set):
75
"""
76
Типы телефонов
77
"""
78
def add(self, telephoneType):
79
assert telephoneType not in self
80
set.add(self, telephoneType)

На строке 79 стоит запрет на добавление к множеству типов телефонов элемента если он там уже
есть.
82 class Telephone:
83
"""
84
Телефон
85
"""
86
def __init__(self, telephone, telephoneType):
87
self.number = telephone
88
self.type = telephoneType
89
90
def __hash__(self):
91
return hash(self.number)
92
93
def __eq__(self, other):
94
return self.number == other.number

Телефон определяется его типом и номером.

96 class Telephones(set):
97
"""
98
Телефоны
99
"""
100
def __init__(self, telephoneTypes):
101
set.__init__(self)
102
self.telephoneTypes = telephoneTypes
103
104
def add(self, telephone):
105
assert telephone not in self
106
assert telephone.type in self.telephoneTypes
107
set.add(self, telephone)

На строке 105 стоит запрет на добавление к множеству телефонов элемента с уже существующим
номером и на строке 106 если его типа нет в telephoneTypes.
109 class TelephoneRecord:
110
"""
111
Запись в телефонном справочнике
112
"""
113
def __init__(self, telephone, collaborator):
114
self.telephone = telephone
115
self.collaborator = collaborator
116
117
def __hash__(self):
118
return hash((self.telephone, self.collaborator))
119
120
def __eq__(self, other):

121
122

return self.telephone == other.telephone and \
self.collaborator == other.collaborator

Запись в телефонном справочнике должна ссылаться на телефон и сотрудника.
124 class TelephoneDir(set):
125
"""
126
Телефонный справочник
127
"""
128
def __init__(self, telephones, subdivision):
129
set.__init__(self)
130
self.telephones = telephones
131
self.subdivision = subdivision
132
133
def add(self, telephoneRecord):
134
assert telephoneRecord.telephone in self.telephones
135
assert telephoneRecord.collaborator in self.subdivision
136
assert telephoneRecord not in self
137
set.add(self, telephoneRecord)

На строке 134 стоит запрет на добавление к множеству телефона, если его нет среди телефонов
справочника. Аналогично, на строке 135, запрет для подразделений. Строка 136 запрещает добавлять
записи в телефонный справочник, если они уже там есть.
139 if __name__ == ’__main__’:
140
import os, csv
141
142
subdivision = {}

143
for rec in csv.reader(open(os.path.join(os.curdir, ’subdivision1.csv’),
’rb’), delimiter=’;’):
144
subdivision[rec[0]] = Subdivision(rec[0])
145
if rec[1]:
146
subdivision[rec[1]].addSubdivision(subdivision[rec[0]])
147
else:
148
telephoneDir = TelephoneDir(Telephones(TelephoneTypes()),
subdivision[rec[0]])
149
150
telephones, telephoneTypes, collaborators = {}, {}, {}
151
for rec in csv.reader(open(os.path.join(os.curdir, ’ssu1.csv’), ’rb’),
delimiter=’;’):
152
if rec[6] not in telephoneTypes:
153
telephoneTypes[rec[6]] =