основе модуля shelve и на основе модуля pickle, в которой каждая запись сохраняется в отдельном файле, - этого вполне достаточно для хранения простых данных. Наши записи представлены простыми словарями, которые обеспечивают более простой и понятный доступ к полям, чем списки (то есть не по числовым индексам, а по ключам). Однако словари имеют некоторые ограничения, которые могут оказаться существенными по мере разработки программы.
Во-первых, у нас не предусмотрено место для централизованного хранения логики обработки записей. Операции извлечения фамилии и увеличения оклада, например, могут выполняться так:
>>> import shelve
>>> db = shelve.open(‘people-shelve')
>>> bob = db[‘bob']
>>> bob[‘name'].split()[-1] # вернет фамилию Боба ‘Smith’
>>> sue = db[‘sue']
>>> sue[‘pay'] *= 1.25 # увеличит оклад Сью
>>> sue[‘pay']
75000.0
>>> db[‘sue'] = sue >>> db.close()
Такое решение вполне пригодно для небольших программ. Но если когда-нибудь потребуется изменить логику извлечения фамилии или увеличения оклада, нам, возможно, придется обновить подобный программный код во множестве мест в программе. На практике даже просто отыскать все такие фрагменты может оказаться достаточно сложным делом - копирование одинаковых фрагментов программного кода рано или поздно обязательно даст знать о себе.
Подобные фрагменты предпочтительнее скрывать, то есть
Другой недостаток использования словарей для представления записей заключается в том, что со временем их становится трудно расширять. Например, представьте, что имеется набор полей данных или различные процедуры, увеличивающие оклад для разных сотрудников по-разному (например, кто-то может получать ежегодную прибавку, а кто-то - нет). Если нам когда-нибудь потребуется расширить программу, сделать это будет очень сложно, так как нет простого и естественного способа расширить простые словари. С учетом дальнейшего роста нам
хотелось бы, чтобы наше программное обеспечение предусматривало возможность расширения и настройки естественными способами.
Если вы уже погружались в изучение Python, то, наверное, знаете, что это тот случай, когда начинает проявляться привлекательность ООП:
Благодаря ООП появляется возможность связать логику обработки записей с самими записями - классы представляют собой программные единицы, объединяющие логику и данные, а наследование позволяет легко избежать избыточности программного кода.
Благодаря ООП можно скрыть детали реализации таких операций, как обработка имени или увеличение оклада, внутри методов - то есть в дальнейшем мы легко сможем изменять реализацию методов, не влияя на работоспособность программного кода, использующего их.
Применение ООП обеспечивает естественный способ дальнейшего расширения. Классы могут расширяться и специализироваться за счет создания новых подклассов, без изменения или нарушения работоспособности существующего программного кода.
Таким образом, в объектно-ориентированном программировании мы специализируем и повторно используем программный код, а не переписываем его заново. ООП в Python является дополнительной возможностью, которая, честно признаться, лучше подходит для решения стратегических, а не тактических задач. ООП лучше подходит, когда у вас имеется время для предварительного планирования, что может оказаться непозволительной роскошью, когда ваши пользователи уже начали штурмовать ворота.
Преимущества структурирования и повторного использования программного кода в крупных системах, которые продолжают развиваться в течение длительного времени, перевешивают затраты на изучение ООП и способны существенно сократить время разработки. Даже в нашем простом случае возможность специализации и снижения избыточности, которую дают классы, может оказаться решающим преимуществом.
Использование классов
ООП в Python отличается простотой использования, в значительной степени благодаря динамической модели типов. Фактически программировать в объектно-ориентированном стиле настолько просто, что я сразу же перейду к примеру: пример 1.14 реализует наши записи уже не в виде словарей, а в виде экземпляров класса.
class Person:
def __init__(self, name, age, pay=0, job=None):
self.name = name self.age = age self.pay = pay self.job = job
if__name__== ‘__main__’:
bob = Person(‘Bob Smith’, 42, 30000, ‘software’) sue = Person(‘Sue Jones’, 45, 40000, ‘hardware’) print(bob.name, sue.pay)
print(bob.name.split()[-1]) sue.pay *= 1.10 print(sue.pay)