Сохраняет только одну запись вместо добавления в словарь

#python #dictionary #append

#python #словарь #добавить

Вопрос:

Я хочу взять имя пользователя и его номер телефона у конечного пользователя и добавить в словарь. Я начал с пустого словаря.

После того, как первый пользователь введет данные, программа сообщит, что добавлена новая запись, и отобразит то, что находится внутри обновленного словаря. Пока все работает нормально.

Когда второй пользователь вводит данные, он должен делать то же самое:

  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'} 
>>> 
  

Комментарии:

1. Пожалуйста, сделайте отступ в своем коде.

2. Я думаю, вы хотите использовать raw_input вместо input , поскольку последний оценивает введенный текст как выражение python.

Ответ №1:

Я думаю, вы серьезно перепутали, что должно быть атрибутом класса, а что нет. Подумайте об этом так: в вашем классе phonebook есть dictionary, следовательно, dictionary должен быть атрибутом. Имя и телефон добавляемого пользователя должны быть параметрами 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}
  

Обновление: что касается обновления вашего вопроса — не уверен, чего вы пытаетесь достичь? Сохранение dict при вызовах скрипта? Обратите внимание, что вы запрашиваете только одно имя и телефон и добавляете их в телефонную книгу. При повторном запуске программы все снова становится новым и чистым, поэтому, конечно, информация, сохраненная с предыдущего вызова, отсутствует.

Если вам нужно постоянное хранилище, рассмотрите возможность использования pickle , или shelve или даже какой-либо базы данных (например, sqlite3 модуль предоставляет встроенный доступ к SQLite DB)

Комментарии:

1. Спасибо за указатель Eli. Я перенес имя, параметры телефона в функцию adddata, где это имеет больше смысла. Но мой вывод не имеет никакого значения (опять же, я хочу принять входные данные от пользователя)

2. @Kalyan: пожалуйста, обновите свой вопрос точным кодом, который вы пытаетесь выполнить сейчас (но сохраните старый код там тоже для справки)

3. Спасибо за указатель Eli. Я перенес имя, параметры телефона в функцию adddata, где это имеет больше смысла. Но мой вывод не имеет никакого значения (опять же, я хочу принять входные данные от пользователя) >>> ============================= ПЕРЕЗАПУСК========================== >>> Введите имя пользователя -> abc Введите номер телефона пользователя -> 12345 Добавлена новая запись в телефонной книге — abc:12345 {‘abc’: ‘12345’} >>> ================================ ПЕРЕЗАПУСК =================== >>> Введите имя пользователя -> ijk Введите номер телефона пользователя -> 24680 Добавлена новая запись в телефонной книге — ijk: 24680 {‘ijk’: ‘24680’} >>>

4. Код здесь class phonebook: def init (self): self.allphones = {} def adddata(self, name, phone): self.allphones[name] = phone # добавить к словарю печать (‘Добавлена новая запись телефонной книги — {0}:{1}’. формат(имя, телефон)) # подтвердите ввод print (self.allphones) # сбросьте полные данные телефонной книги name = input (‘Введите имя пользователя -> ‘) phone = input(‘Введите номер телефона пользователя -> ‘) adding = phonebook() adding.adddata(имя, телефон)

5. @Kalyan: нет возможности понять, что здесь происходит. Отредактируйте ответ с помощью форматированного кода

Ответ №2:

Похоже, вам нужна телефонная книга, которая сохраняется между вызовами вашего скрипта. shelve модуль предоставляет постоянный объект, подобный словарю. Если вы замените self.allphones dictionary таким объектом, вы получите постоянную телефонную книгу:

 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 всегда есть неизменяемый объект, такой как string, то вызовы writeback=True и .sync() могут быть опущены. Они нужны вам, когда вы хотите отслеживать несколько телефонных номеров на name в объекте list и использовать тот же синтаксис для работы с shelve, что и для обычного словаря Python.

Пример

 $ 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'}
  

Ответ №3:

Будут ли у пользователей разные имена? Если нет, то первый ответ Эли имеет смысл (его второй ответ также является хорошим моментом, словарь, вероятно, должен быть атрибутом экземпляра, а не атрибутом класса).

Тем не менее, ваш класс работает для меня. Возможно, разница в том, как я это тестирую. Я вырезал и пропустил ваш класс, чтобы создать следующий файл (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 сначала гарантирует, что правильный список существует (по умолчанию [], если это не так), а затем добавляет к нему.