[Tutor] A problem with the shelve module

Kent Johnson kent_johnson at skillsoft.com
Sun Sep 5 18:50:25 CEST 2004


Mark,

This is kind of a subtle problem with variable scoping and the way you are 
calling Address() recursively. I'm not sure I can explain it very well but 
I will try.

Every time you call a function, it gets a new set of local variables. This 
is true even if you are calling the same function recursively. So every 
time you call Address(), you make a new book object. The book that you are 
using to lookup MarkK is not the same book that you added MarkK to because 
it is in a different invocation of Address()! So the lookup fails with a 
KeyError.

I can see two ways to fix the problem. The simplest way is just to move the 
book creation outside the Address function. This makes book a global 
variable, so every call to Address uses the same book. This would look like 
this:
book = shelve.open("Address book")
def Address():
   ...

Another way to fix it would be to change Address from a recursive function 
to a looping function. This would look like this:
def Address():
   book = shelve.open("Address book")
   choice = -1  # dummy init for choice
   while choice != 6:
     # get the user input
     if choice == '1':
       # handle choice 1
     #etc

Kent

PS A question for the other tutors - does this recursive style of user 
input make you nervous? I don't much like it but I don't know if it is just 
because it is unfamiliar...my gut feeling is you could get in trouble with 
it. I guess the OP is one example of how!

At 05:56 PM 9/5/2004 +0200, Mark Kels wrote:
>Hi all,
>Its my again (the guy with the bad english... :-/ ).
>
>I started to build a personal organizer useing the module "shelve".
>The problem is that I get an error in the module (?!) .
>here is the code of the function that makes the problem:
>
>[Start of code]
>#The adress book function
>def Address():
>     print
>     print "1.Open a book"
>     print "2.View a book"
>     print "3.Add name"
>     print "4.Delete name"
>     print "5.Edit name"
>     print "6.Back"
>     print
>     Achoice=raw_input(">>> ")
>     book=shelve.open("Address book")
>     if Achoice=="3":
>         addname=raw_input("Name: ")
>         phone=raw_input("Phone number(type 'none' if you wabt to add
>Phone number later): ")
>         Addressnum=raw_input("Address(type 'none' if you wabt to add
>Address later): ")
>         ICQ=raw_input("ICQ number(type 'none' if you want add ICQ later): ")
>         book[addname]=(addname,phone,Addressnum,ICQ)
>         Address()
>     elif Achoice=="2":
>         namecheck=raw_input("Enter the name you want to view: ")
>         book[namecheck]
>         Address()
>[End of code]
>
>And the error I get is:
>Traceback (most recent call last):
>[Start of code]
>Enter the name you want to view: MarkK
>   File "C:\ab.py", line 57, in ?
>     startmenu()
>   File "C:\ab.py", line 45, in startmenu
>     Address()
>   File "C:\ab.py", line 28, in Address
>     Address()
>   File "C:\ab.py", line 28, in Address
>     Address()
>   File "C:\ab.py", line 32, in Address
>     Address()
>   File "C:\ab.py", line 28, in Address
>     Address()
>   File "C:\ab.py", line 31, in Address
>     book[namecheck]
>   File "C:\DOCUME~1\AMP-TECH\DESKTOP\MARK\program\lib\shelve.py", line 
> 118, in _
>_getitem__
>     f = StringIO(self.dict[key])
>   File "C:\DOCUME~1\AMP-TECH\DESKTOP\MARK\program\lib\bsddb\__init__.py", 
> line 1
>16, in __getitem__
>     return self.db[key]
>KeyError: 'MarkK'
>[End of code]
>
>Thanks!!
>_______________________________________________
>Tutor maillist  -  Tutor at python.org
>http://mail.python.org/mailman/listinfo/tutor



More information about the Tutor mailing list