print('no such key "% "!keyelsefor field in fieldnamesprint(field ljust(maxfield)'=>'getattr(recordfield)this script uses the getattr built-in function to fetch an object' attribute when given its name stringand the ljust left-justify method of strings to align outputs (max fieldderived from generator expressionis the length of the longest field namewhen runthis script goes into loopinputting keys from the interactive user (technicallyfrom the standard input streamwhich is usually console windowand displaying the fetched records field by field an empty line ends the session if our shelve of class instances is still in the state we left it near the end of the last section\pp \previewdump_db_classes py bob =bob smith sue =sue jones tom =tom doe smith doe we can then use our new script to query the object database interactivelyby key\pp \previewpeopleinteract_query py key=sue name =sue jones age = job =hardware pay = key=nobody no such key "nobody"key=example - goes further and allows interactive updates for an input keyit inputs values for each field and either updates an existing record or creates new object and stores it under the key example - pp \preview\peopleinteract_update py interactive updates import shelve from person import person fieldnames ('name''age''job''pay'db shelve open('class-shelve'while truekey input('\nkey='if not keybreak sneak preview