# contact_manager.pyimport jsonimport csvimport osCONTACTS_FILE = "contacts.json"CSV_EXPORT_FILE = "contacts_export.csv"def load_contacts(): """从 JSON 文件加载联系人""" if not os.path.exists(CONTACTS_FILE): return [] try: with open(CONTACTS_FILE, "r", encoding="utf-8") as f: return json.load(f) except (json.JSONDecodeError, IOError) as e: print(f"⚠️ 警告:无法读取联系人文件,使用空列表。错误: {e}") return []def save_contacts(contacts): """将联系人保存到 JSON 文件""" try: with open(CONTACTS_FILE, "w", encoding="utf-8") as f: json.dump(contacts, f, ensure_ascii=False, indent=2) except IOError as e: print(f"❌ 保存失败: {e}")def find_contact_by_name(contacts, name): """按姓名精确查找(用于编辑/删除)""" for i, contact in enumerate(contacts): if contact["name"] == name: return i, contact return None, Nonedef search_contact(contacts): """支持按姓名、电话、邮箱模糊搜索""" keyword = input("请输入搜索关键词(姓名/电话/邮箱): ").strip() if not keyword: print("❌ 请输入关键词!") return results = [] keyword_lower = keyword.lower() for contact in contacts: if (keyword_lower in contact["name"].lower() or keyword_lower in contact["phone"].lower() or keyword_lower in contact["email"].lower()): results.append(contact) if results: print(f"\n🔍 找到 {len(results)} 个结果:") for c in results: print(f" {c['name']} | {c['phone']} | {c['email']}") else: print("❌ 未找到匹配的联系人") print()def add_contact(contacts): """添加新联系人""" name = input("姓名: ").strip() if not name: print("❌ 姓名不能为空!") return if any(c["name"] == name for c in contacts): print(f"❌ 联系人 '{name}' 已存在!") return phone = input("电话: ").strip() email = input("邮箱: ").strip() contacts.append({ "name": name, "phone": phone, "email": email }) save_contacts(contacts) print(f"✅ 联系人 '{name}' 已添加!")def list_contacts(contacts): """列出所有联系人""" if not contacts: print("📭 通讯录为空") return print("\n📋 所有联系人:") for i, contact in enumerate(contacts, 1): print(f"{i}. {contact['name']} | {contact['phone']} | {contact['email']}") print()def edit_contact(contacts): """编辑现有联系人""" name = input("请输入要编辑的联系人姓名: ").strip() if not name: print("❌ 请输入姓名!") return index, contact = find_contact_by_name(contacts, name) if contact is None: print("❌ 未找到该联系人") return print(f"\n当前信息: {contact['name']} | {contact['phone']} | {contact['email']}") print("留空表示不修改") new_name = input(f"新姓名 [{contact['name']}]: ").strip() new_phone = input(f"新电话 [{contact['phone']}]: ").strip() new_email = input(f"新邮箱 [{contact['email']}]: ").strip() # 更新字段(非空才覆盖) if new_name: # 检查新姓名是否冲突(排除自己) if new_name != contact["name"] and any(c["name"] == new_name for c in contacts): print(f"❌ 姓名 '{new_name}' 已被其他联系人使用!") return contact["name"] = new_name if new_phone: contact["phone"] = new_phone if new_email: contact["email"] = new_email save_contacts(contacts) print(f"✅ 联系人已更新为: {contact['name']} | {contact['phone']} | {contact['email']}")def delete_contact(contacts): """删除联系人""" name = input("请输入要删除的姓名: ").strip() if not name: print("❌ 请输入姓名!") return index, contact = find_contact_by_name(contacts, name) if contact is None: print("❌ 未找到该联系人") return del contacts[index] save_contacts(contacts) print(f"✅ 联系人 '{name}' 已删除!")def export_to_csv(contacts): """导出联系人到 CSV 文件""" if not contacts: print("📭 通讯录为空,无法导出") return try: with open(CSV_EXPORT_FILE, "w", newline="", encoding="utf-8-sig") as f: writer = csv.DictWriter(f, fieldnames=["name", "phone", "email"]) writer.writeheader() writer.writerows(contacts) print(f"✅ 已导出 {len(contacts)} 条联系人到 {CSV_EXPORT_FILE}") except IOError as e: print(f"❌ 导出失败: {e}")def main(): """主程序循环""" contacts = load_contacts() print("📞 欢迎使用增强版简易通讯录!") while True: print("\n请选择操作:") print("1. 添加联系人") print("2. 查看所有联系人") print("3. 搜索联系人(姓名/电话/邮箱)") print("4. 编辑联系人") print("5. 删除联系人") print("6. 导出为 CSV") print("7. 退出") choice = input("请输入选项 (1-7): ").strip() if choice == "1": add_contact(contacts) elif choice == "2": list_contacts(contacts) elif choice == "3": search_contact(contacts) elif choice == "4": edit_contact(contacts) elif choice == "5": delete_contact(contacts) elif choice == "6": export_to_csv(contacts) elif choice == "7": print("👋 再见!") break else: print("❌ 无效选项,请输入 1-7")if __name__ == "__main__": main()