Пока что наша программа состоит из экземпляров классов, реализованных в предыдущем разделе, которые сохранены в файле хранилища. В качестве хранилища она делает достаточно, но для доступа к содержимому и работы с ним нам потребуется запускать другие сценарии или вводить программный код в интерактивной оболочке. Улучшить ситуацию достаточно просто: необходимо написать универсальную программу, которая будет взаимодействовать с пользователем либо с помощью окна консоли, либо с помощью графического интерфейса.
Интерфейс командной строки к хранилищу
Начнем с наиболее простого варианта. В самом простом виде интерфейс к базе данных должен давать пользователям возможность вводить ключи и значения в окне консоли (вместо того чтобы писать программный код на языке Python). Сценарий в примере 1.21 реализует простейший цикл интерактивных взаимодействий, позволяя пользователю запрашивать объекты, имеющиеся в хранилище.
# интерактивные запросы import shelve
fieldnames = (‘name’, ‘age’, ‘job’, ‘pay’) maxfield = max(len(f) for f in fieldnames) db = shelve.open(‘class-shelve’)
while True:
key = input(‘\nKey? => ‘) # ключ или пустая строка, возбуждает исключение
# при вводе EOF
if not key: break try:
record = db[key] # извлечь запись по ключу и вывести except:
print(‘No such key “%s”!’ % key) else:
for field in fieldnames:
print(field.ljust(maxfield), ‘=>’, getattr(record, field))
Для извлечения значений атрибутов в этом сценарии используется встроенная функция getattr, а для форматирования вывода используется строковый метод ljust, выравнивающий строку по левому краю (значение maxfield, порожденное выражением-генератором, представляет длину наибольшего имени поля). После запуска сценария он входит в цикл, предлагает пользователю ввести ключ (со стандартного потока ввода, который обычно соответствует окну консоли) и отображает извлеченную запись поле за полем. Ввод пустой строки завершает сеанс работы со сценарием. Предположим, хранилище находится в том же состоянии, в каком мы его оставили ближе к концу предыдущего раздела:
...\PP4E\Preview> dump_db_classes.py
bob =>
Bob Smith 30000 sue =>
Sue Jones 50000.0 tom =>
Tom Doe 65000.0 Smith Doe
Мы сможем использовать наш новый сценарий для запроса объектов из базы данных в интерактивном режиме:
...\PP4E\Preview> peopleinteract_query.py
Key? => sue name => Sue Jones
age => 45 job => hardware pay => 50000.0
Key? => nobody No such key “nobody”!
Key? =>
Сценарий в примере 1.22 является следующим шагом к созданию интерфейса, позволяющим вносить изменения в интерактивном режиме. Для заданного ключа он позволяет ввести значения для каждого из полей и либо изменяет существующую запись, либо создает новую, после чего сохраняет ее с указанным ключом.
# интерактивные изменения
import shelve
from person import Person
fieldnames = (‘name’, ‘age’, ‘job’, ‘pay’)
db = shelve.open(‘class-shelve’) while True:
key = input(‘\nKey? => ‘) if not key: break if key in db:
record = db[key] # изменить существующую
else: # или создать новую запись
record = Person(name=’?’, age=’?’) # для eval: строки в кавычках for field in fieldnames:
currval = getattr(record, field)
newtext = input(‘\t[%s]=%s\n\t\tnew?=>’ % (field, currval)) if newtext:
setattr(record, field, eval(newtext)) db[key] = record db.close()
Обратите внимание, что для преобразования введенных значений в этом сценарии используется функция eval (это позволяет вводить любые объекты Python, но это означает, что строки при вводе должны заключаться в кавычки). Функция setattr присваивает значение атрибуту, имя которого задается строкой. Этот сценарий позволит добавлять или изменять любое количество записей - чтобы сохранить прежнее значение поля в записи, достаточно просто нажать клавишу Enter в ответ на просьбу ввести новое значение:
Key? => tom
[name]=Tom Doe new?=>
[age]=50
new?=>56
[job]=None
new?=>'mgr'
[pay]=65000.0
new?=>90000
Key? => nobody [name]=?
new?=>'John Doh'
[age]=?
new?=>55
[job]=None
new?=>
[pay]=0
new?=>None
Key? =>
Этот сценарий все еще очень прост (в нем, например, не предусмотрена обработка ошибок), но пользоваться им гораздо удобнее, чем вручную открывать и вносить изменения в хранилище в интерактивной оболочке Python, особенно для тех, кто не занимается программированием. Запустим сценарий
Key? => tom name => Tom Doe age => 56 job => mgr pay => 90000
Key? => nobody name => John Doh age => 55 job => None pay => None
Key? =>
Шаг 5: добавляем графический интерфейс