You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现可调用带属性类的菜单并将数据保存至CSV?

问题修复与最简实现方案

原代码核心问题

  • 类定义顺序错误:User类在Logistics_System实例化后才定义,导致调用时找不到类
  • 继承关系混乱:User无需继承物流系统类,应作为独立实体存在
  • 方法定义缺陷:user_input缺少实例/类参数,未定义的变量直接使用
  • 缺失CSV持久化逻辑:没有实现数据的读写存储
  • 菜单逻辑不合理:除选项1外直接退出,递归调用菜单易引发栈溢出

最简实现代码

import csv
from typing import List

# 1. 定义用户实体类
class User:
    def __init__(self, first_name: str, last_name: str, user_id: str, address: str, phone: int, password: str):
        self.first_name = first_name
        self.last_name = last_name
        self.email = f"{first_name.lower()}.{last_name.lower()}@expressdelivery.com"
        self.user_id = user_id
        self.address = address
        self.phone = phone
        self.password = password

    # 转换为CSV行数据
    def to_csv_row(self) -> list:
        return [self.first_name, self.last_name, self.email, self.user_id, self.address, self.phone, self.password]

    # 从CSV行数据创建User实例
    @classmethod
    def from_csv_row(cls, row: list) -> 'User':
        return cls(
            first_name=row[0],
            last_name=row[1],
            user_id=row[3],
            address=row[4],
            phone=int(row[5]),
            password=row[6]
        )

# 2. 定义物流系统核心类,负责菜单与数据操作
class LogisticsSystem:
    def __init__(self, csv_path: str = "users.csv"):
        self.csv_path = csv_path
        self.users: List[User] = self._load_users_from_csv()
        print("Welcome to Express Delivery")

    # 从CSV加载用户数据
    def _load_users_from_csv(self) -> List[User]:
        users = []
        try:
            with open(self.csv_path, 'r', newline='', encoding='utf-8') as f:
                reader = csv.reader(f)
                next(reader)  # 跳过表头
                for row in reader:
                    users.append(User.from_csv_row(row))
        except FileNotFoundError:
            # 文件不存在时自动创建表头
            self._save_users_to_csv(users, write_header=True)
        return users

    # 保存用户数据到CSV
    def _save_users_to_csv(self, users: List[User], write_header: bool = False):
        with open(self.csv_path, 'w', newline='', encoding='utf-8') as f:
            writer = csv.writer(f)
            if write_header:
                writer.writerow(["First Name", "Last Name", "Email", "ID", "Address", "Phone", "Password"])
            for user in users:
                writer.writerow(user.to_csv_row())

    # 用户操作子菜单
    def user_management_menu(self):
        while True:
            print("\n--- 用户管理 ---")
            print("[1]. 添加用户")
            print("[2]. 删除用户")
            print("[3]. 修改用户")
            print("[4]. 返回主菜单")
            try:
                opt = int(input("选择操作: "))
                if opt == 1:
                    self._add_user()
                elif opt == 2:
                    self._remove_user()
                elif opt == 3:
                    self._update_user()
                elif opt == 4:
                    break
                else:
                    print("无效选项,请重新输入")
            except ValueError:
                print("输入错误,请输入数字")

    # 添加用户
    def _add_user(self):
        try:
            first = input("名字: ")
            last = input("姓氏: ")
            user_id = input("用户ID: ")
            address = input("地址: ")
            phone = int(input("手机号: "))
            password = input("密码: ")
            new_user = User(first, last, user_id, address, phone, password)
            self.users.append(new_user)
            self._save_users_to_csv(self.users)
            print("用户添加成功!")
        except ValueError:
            print("手机号格式错误,必须是整数")

    # 删除用户
    def _remove_user(self):
        user_id = input("输入要删除的用户ID: ")
        for idx, user in enumerate(self.users):
            if user.user_id == user_id:
                del self.users[idx]
                self._save_users_to_csv(self.users)
                print("用户删除成功!")
                return
        print("未找到该用户")

    # 修改用户
    def _update_user(self):
        user_id = input("输入要修改的用户ID: ")
        for user in self.users:
            if user.user_id == user_id:
                print("留空则保持原数据")
                user.first_name = input(f"名字 ({user.first_name}): ") or user.first_name
                user.last_name = input(f"姓氏 ({user.last_name}): ") or user.last_name
                user.address = input(f"地址 ({user.address}): ") or user.address
                phone_input = input(f"手机号 ({user.phone}): ")
                user.phone = int(phone_input) if phone_input else user.phone
                user.password = input(f"密码: ") or user.password
                user.email = f"{user.first_name.lower()}.{user.last_name.lower()}@expressdelivery.com"
                self._save_users_to_csv(self.users)
                print("用户修改成功!")
                return
        print("未找到该用户")

    # 主菜单
    def main_menu(self):
        while True:
            print("\n--- 主菜单 ---")
            print("[1]. 增删改: 用户")
            print("[2]. 增删改: 企业客户")
            print("[3]. 增删改: 个人客户")
            print("[4]. 添加自行车到系统")
            print("[5]. 添加卡车到系统")
            print("[6]. 添加船只到系统")
            print("[7]. 创建货运订单")
            print("[8]. 向订单添加物品")
            print("[9]. 更新订单状态")
            print("[0]. 退出")
            try:
                option = int(input("选择操作: "))
                if option == 1:
                    self.user_management_menu()
                elif option == 0:
                    print("程序退出")
                    break
                else:
                    print("该功能暂未实现")
            except ValueError:
                print("输入错误,请输入有效数字")

# 启动系统
if __name__ == "__main__":
    system = LogisticsSystem()
    system.main_menu()

实现说明

  1. 实体类与CSV交互:User类通过to_csv_row和from_csv_row方法实现对象与CSV行数据的双向转换,保证数据格式统一
  2. 数据持久化:LogisticsSystem类负责加载和保存CSV数据,文件不存在时自动创建表头
  3. 菜单分层:主菜单调用子菜单(如用户管理),避免逻辑混乱,用循环替代递归防止栈溢出
  4. 增删改逻辑:所有用户操作直接修改内存中的用户列表,操作完成后立即写入CSV,保证数据一致性
  5. 基础错误处理:针对输入格式错误(如非整数手机号)做了校验,提升程序稳定性

你可以按照此模式扩展其他实体(如企业客户、交通工具等),只需复制User类的结构,修改属性和CSV交互方法即可。

内容的提问来源于stack exchange,提问作者Gino Chen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 07:25:17