【问题标题】:My Python Code failed to saved multiple stream of data to storage file我的 Python 代码未能将多个数据流保存到存储文件
【发布时间】:2025-11-22 16:10:02
【问题描述】:

问题定义

创建您自己的命令行地址簿程序,您可以使用该程序浏览、添加、修改、删除或搜索您的联系人,例如朋友、家人和同事以及他们的信息,例如电子邮件地址和/或电话号码。必须存储详细信息以供以后检索。

基于上述问题描述,我能够开发出以下程序,

我目前面临的挑战是;
1.本地存储只保存一个联系人,旧联系人总是被覆盖。我希望对象的每个实例都将不同的联系人保存到同一个文件(电话列表)
2.通过错误的contact_del方法虽然它做了它应该做的事情,有人可以告诉我那部分代码有什么问题以及为什么我会收到错误。最后我希望那个错误被抑制。

import pickle
#   Declare the Class
class phone_book:
    def __init__(self):
        """ Initialize The Phone Book"""
        print('This is a command Line phone Book Directory')


    def add_detail(self):
        """ Detail of our Contacts is being collected"""
        address_book = {}
        address_value = []

        #   Accepting Value from the User
        print('Let add our friends Details')
        address_name = input('Enter name : ')
        address_phone = int(input('Enter phone Number : '))
        address_email = input('enter email : ')
        addess_Gtype = input('Specify Contact Group Type : ')
        address_value.append(address_phone)
        address_value.append(address_email)
        address_value.append(addess_Gtype)

        for i in address_value:
            address_book[address_name] = address_value
            #   Sending our Data to Permanent Storage
            with open("phonelist.txt", "wb") as myFile:
                pickle._dump(address_book, myFile)

    # Declare Function that will enable us to modify the data enter
    @classmethod
    def detail_modify(cls):
        """ We are Modifying our old friends Details"""
        modify_contact = input('Enter the Name of the to modify : ')
        with open("phonelist.txt", "rb") as myFile:
            address_book = pickle._load(myFile)
            # Iterate over the supply name
            for name, name_detail in address_book.items():
                if modify_contact not in name:
                    print('The contact does not exist')
                else:
                    print('We are ready to modify  Mr :', name)
                    address_phone = int(input('Enter phone Number : '))
                    address_email = input('enter email : ')
                    addess_Gtype = input('Specify Contact Group Type : ')
                    name_detail[0] = address_phone
                    name_detail[1] = address_email
                    name_detail[2] = addess_Gtype

                    # Finally we updating the Details enter
                    for i in name_detail:
                        address_book[name] = name_detail
                        #   Sending our Data to Permanent Storage
                        with open("phonelist.txt", "wb") as myFile:
                            pickle._dump(address_book, myFile)

    # Declare a function that Search for Keywords in the directory
    @classmethod
    def phone_search(cls):
        """ Return Contact Details based on the Keyword Enter"""
        keyword = input('Enter word you are searching for : ')
        with open("phonelist.txt", "rb") as myFile:
            address_book = pickle._load(myFile)


        #   Iteration over the received data from the storage
        for name, name_detail in address_book.items():
            if keyword in name or name_detail:
                print(address_book)

            else:
                print("Keyword not Found")

    # Were are removing people we are no more in friendship with
    @classmethod
    def contact_del(cls):
        """ We are deleting Contact we are done with friendship"""
        with open("phonelist.txt", "rb") as myFile:
            address_book = pickle._load(myFile)
        contact_remove = input('Enter name of Contact to Removed : ')
        for name, name_detail in address_book.items():
            if contact_remove == name:
                del address_book[contact_remove]
                print(contact_remove, 'Successfully removed')
            # Updating Our Storage again
            with open("phonelist.txt", "wb") as myFile:
                pickle._dump(address_book, myFile)
            else:
                print('Name Supply is not valid')

    # Sending the number of Phone contact to output Screen
    @classmethod
    def contact_view(cls):
        """ Displaying Our contacts Details"""
        with open("phonelist.txt", "rb") as myFile:
            address_book = pickle._load(myFile)
        print(address_book, 'Number of Contacts ',  len(address_book))

# Running below instance of object only retain last object the first
phone_book.contact_view()
contact1 = phone_book()
contact1.add_detail()
contact2 = phone_book()
contact2.add_detail()
phone_book.contact_view()
phone_book.phone_search()
phone_book.contact_del()

尽管调用方法(phone_book.contact_del()) 上面的错误删除了预期的用户,请参阅下面的phone_book.contact_del() 的输出

【问题讨论】:

    标签: python dictionary pickle


    【解决方案1】:

    旧联系人总是被覆盖。

    您正在以“写入”模式打开文件,这将覆盖任何具有相同名称的文件。您需要使用“附加”模式。将open("phonelist.txt", "wb") 更改为open("phonelist.txt", "ab") 请参阅this documentation,特别是关于mode 参数的部分。

    contact_del 方法通过错误,虽然它做了它应该做的事情

    问题出在这里:

    for name, name_detail in address_book.items():
        if contact_remove == name:
            del address_book[contact_remove]  # Don't do this
    

    您在迭代字典中的值时正在修改字典,这会导致RuntimeError: dictionary changed size during iteration。通常,不要在 for 循环中更改字典(或列表!)。修改循环内部的数据结构会对其进行迭代可能会导致意外的错误。

    在您的情况下,一个简单的 if 语句就足够了:

    # Check if the requested contact is in the address book
    if contact_remove in address_book:
        del address_book[contact_remove]
    

    【讨论】:

    • 感谢您的快速回复,我已更新代码(我的代码现在使用 mode="ab")以反映您的回复,但数据未写入磁盘。我在window10上并运行python3.4(64位)。除了模式之外,我需要在代码中更改什么吗?提前谢谢
    最近更新 更多