只保留一条记录而非追加到字典
我想从用户那里获取姓名和电话号码,然后把这些信息放到一个字典里。我一开始是从一个空字典开始的。
当第一个用户输入数据后,程序会显示“新增条目已添加”,并展示更新后的字典内容。到目前为止,这部分运行得很好。
当第二个用户输入数据时,程序应该做同样的事情:
- 显示“新增条目已添加”
- 展示字典里的所有内容,也就是第一个用户和第二个用户的输入。但现在并没有按预期工作。它只显示第二个用户的输入,而没有显示第一个用户的输入。
有人能告诉我为什么没有把数据添加到已有的信息里吗?每次我只看到一个条目(就是最新输入的那个)。
这是我的程序:
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()
这是更新后的程序 <-----------
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)
这是我得到的输出(我想要的结果是 {'abc': '123', 'ghj': '505050'}
) -
>>> ================================ 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'}
>>>
3 个回答
用户会有不同的名字吗?如果没有,那么Eli的第一个回答是有道理的(他的第二个回答也很不错,字典应该是实例属性,而不是类属性)。
不过,你的类对我来说是可以用的。也许差别在于我测试的方式。我复制了你的类,创建了以下文件(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()
如果你想给同一个人添加多个电话号码,我建议你可以这样做(警告:我还没有试过这段代码)
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)
现在,allphones是一个字典,它把名字和电话号码的列表关联起来。add_number首先确保对应的列表存在(如果不存在就默认给一个空列表[]),然后再把号码添加进去。
我觉得你搞错了什么应该是类的属性,什么不应该是。可以这样理解:你的电话簿类里面有一个字典,所以这个字典应该是一个属性。而你要添加的人的名字和电话应该是adddata
这个方法的参数,而不是类的实例变量。
你可以试试这样修改:
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
对我来说,这样打印出来是:
{'bob': 129459, 'joe': 121212}
更新:关于你问题的更新——我不太明白你想要达到什么?是想让字典在脚本运行时保持不变吗?注意你只输入了一个名字和电话,然后把它们加到电话簿里。当你再次运行程序时,一切又都是新的,所以当然不会保留之前运行时的信息。
如果你需要持久存储,可以考虑使用pickle
,或者shelve
,甚至是某种数据库(比如sqlite3
模块提供了内置的SQLite数据库访问)。
看起来你想要一个可以在每次运行脚本时都能保存的电话簿。shelve
模块提供了一种像字典一样的持久化对象。如果你把self.allphones
这个字典换成这种对象,那么你就能得到一个持久化的电话簿:
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)
如果phone
总是一个不可变的对象,比如字符串,那么writeback=True
和.sync()
这两个调用可以省略。当你想要为每个name
跟踪多个电话号码,并且希望用和普通Python字典一样的语法来操作这个shelve时,你就需要它们。
示例
$ 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'}