I want to take person's name and their phone number from the end user and append to a dictionary. I started with an empty dictionary.
After first user inputs the data, the program will say a new entry is added and display what is inside the updated dictionary. It works fine so far.
When the second user inputs the data it should do the same thing:
- Say a new entry is added
- Display everything in the dictionary meaning, first user's as well as second user's input. But it is not working as expected. It only shows the second user's input but not first user's input.
Can someone tell why this is failing to append to the existing data? I see only one entry each time (whoever is the latest).
Here is the program:
class phonebook:
allphones = {} # Empty dictionary
def __init__ (self, name, phone):
self.pername = name
self.perphone = phone
def adddata(self):
phonebook.allphones[self.pername] = self.perphone # append to the dictionary
print ('A new phone book entry added - {0}:{1}'.format(self.pername, self.perphone)) # confirm the input
print (phonebook.allphones) # display what is inside the phonebook
name = input('Type person\'s name --> ')
phone = input('Type phone\'s name --> ')
adding = phonebook(name, phone)
adding.adddata()
Here is the updated program <-----------
class phonebook:
def __init__ (self):
self.allphones = {}
def adddata(self, name, phone):
self.allphones[name] = phone # append to the dictionary
print ('A new phone book entry added - {0}:{1}'.format(name, phone)) # confirm the input
print (self.allphones) # dump the complete phonebook data
name = input('Type person\'s name --> ')
phone = input('Type person\'s phone number --> ')
adding = phonebook()
adding.adddata(name, phone)
Here is the output I get (I want {'abc': '123', 'ghj': '505050'}
as the answer) -
>>> ================================ RESTART ================================
>>>
Type person's name --> abc
Type person's phone number --> 123
A new phone book entry added - abc:123
{'abc': '123'}
>>> ================================ RESTART ================================
>>>
Type person's 开发者_如何学编程name --> ghj
Type person's phone number --> 505050
A new phone book entry added - ghj:505050
{'ghj': '505050'}
>>>
I think you seriously messed up what should be an attribute of the class and what should not. Think of it this way: your phonebook class has a dictionary in it, hence a dictionary should be an attribute. The name and phone of the person you're adding should be parameters to adddata
, not instance vars of the class.
How about this change:
class phonebook:
def __init__ (self):
self.allphones = {} # Empty dictionary
def adddata(self, pername, perphone):
self.allphones[pername] = perphone
# test code
book = phonebook()
book.adddata('joe', 121212)
book.adddata('bob', 129459)
print book.allphones
For me this prints:
{'bob': 129459, 'joe': 121212}
Update: regarding your question update - not sure what you're trying to attain? Persistence of the dict across invocations of the script? Note that you only ask for one name and phone and add them to the phonebook. When you run the program again, it's all new and clean once again, so of course there's no information kept from the previous invocation.
If you need persistent storage, consider using pickle
, or shelve
or even a database of some kind (for example the sqlite3
module provides built-in SQLite DB access)
It seems that you'd like a phonebook that persists between the invocations of your script. shelve
module provides a persistent dictionary-like object. If you replace self.allphones
dictionary by such object then you get a persistent phonebook:
import shelve
from contextlib import closing
try: raw_input = raw_input
except NameError:
raw_input = input # py3k
class phonebook:
def __init__ (self, filename):
self.allphones = shelve.open(filename, protocol=1, writeback=True)
def adddata(self, name, phone):
self.allphones[name] = phone # append to the dictionary
self.allphones.sync()
# confirm the input
print ('A new phone book entry added - {0}:{1}'.format(name, phone))
# dump the complete phonebook data
print (dict(self.allphones.items()))
def close(self):
self.allphones.close()
with closing(phonebook('.phonebook')) as adding:
name = raw_input('Type person\'s name --> ')
phone = raw_input('Type person\'s phone number --> ')
adding.adddata(name, phone)
If phone
is always an immutable object such as string then writeback=True
and .sync()
calls may be omitted. You need them when you'd like to track several phone numbers per name
in a list object and use the same syntax to work with the shelve as for an ordinary Python dictionary.
Example
$ python3 phonebook.py
Type person's name --> a
Type person's phone number --> 1
A new phone book entry added - a:1
{'a': '1'}
$ python3 phonebook.py
Type person's name --> b
Type person's phone number --> 2
A new phone book entry added - b:2
{'a': '1', 'b': '2'}
$ python phonebook.py
Type person's name --> c
Type person's phone number --> 3
A new phone book entry added - c:3
{'a': u'1', 'c': '3', 'b': u'2'}
Are the users going to have distinct names? If not, then Eli's first answer makes sense (his second answer is also a good point, the dictionary should probably be an instance attribute, not a class attribute).
Nonetheless, your class works for me. Perhaps the difference is the way I test it. I cut and past your class, to make the following file (phonebook.py):
class phonebook :
allphones = {}
def __init__ (self, name, phone):
self.pername = name
self.perphone = phone
def adddata(self):
phonebook.allphones[self.pername] = self.perphone # append to the dictionary
print ('A new phone book entry added - {0}:{1}'.format(self.pername, self.perphone)) # confirm the input
print (phonebook.allphones) # display what is inside the phonebook
AA = phonebook('Arkanaoid', '123456789')
AA.adddata()
BB = phonebook('Bongo', '987654321')
BB.adddata()
If you want to be able to append multiple phone numbers to the same person, I would do something like (warning: I haven't tried this code out)
class phonebook :
allphones = {}
def __init__ (self, name):
self.pername = name
def add_number(self, phone)
self.perphone = phone
phonebook.allphones.setdefault(self.pername, [])
phonebook.allphones.append(perphone)
So now allphones is a dictionary mapping names to lists of numbers. add_number first ensures the right list exists (defaulting to [] if it did not), and then appends to it.
精彩评论