只保留一条记录而非追加到字典

1 投票
3 回答
805 浏览
提问于 2025-04-16 15:29

我想从用户那里获取姓名和电话号码,然后把这些信息放到一个字典里。我一开始是从一个空字典开始的。

当第一个用户输入数据后,程序会显示“新增条目已添加”,并展示更新后的字典内容。到目前为止,这部分运行得很好。

当第二个用户输入数据时,程序应该做同样的事情:

  1. 显示“新增条目已添加”
  2. 展示字典里的所有内容,也就是第一个用户和第二个用户的输入。但现在并没有按预期工作。它只显示第二个用户的输入,而没有显示第一个用户的输入。

有人能告诉我为什么没有把数据添加到已有的信息里吗?每次我只看到一个条目(就是最新输入的那个)。

这是我的程序:

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 个回答

0

用户会有不同的名字吗?如果没有,那么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首先确保对应的列表存在(如果不存在就默认给一个空列表[]),然后再把号码添加进去。

3

我觉得你搞错了什么应该是类的属性,什么不应该是。可以这样理解:你的电话簿类里面有一个字典,所以这个字典应该是一个属性。而你要添加的人的名字和电话应该是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数据库访问)。

1

看起来你想要一个可以在每次运行脚本时都能保存的电话簿。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'}

撰写回答