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

如何在CRUD用户管理类中对比两列表并实现安全数据更新?

用户数据CRUD更新功能问题及解决方案

需求说明

我正在学习编程,编写了一套处理基础用户数据的CRUD类,其中actualizar_datos_usuario方法负责更新用户数据。需要实现以下功能:

  • 仅修改用户的个人信息(可选择保留原Cedula作为唯一标识,若修改则需验证合法性)
  • 更新时需验证:若用户输入新的Cedula,该Cedula不能被其他用户占用

原代码

actualizar_datos_usuario方法

def actualizar_datos_usuario(self):
        clear()
            #Buscamos y mostramos los datos del usuario en primer lugar
        ced = int(input("Ingrese la cédula del usuario: "))
        user_found = False
        for i in self.listaUsers:
            if i["Cedula"] == ced:
                for key, value in i.items():
                    print(f"{key}: {value}")
                    user_found = True
                break       
        if not user_found:
            print("Cédula no registrada.")
        print("\n\n[Actualizar usuario al sistema]\n")

        #Luego de mostrar los datos, ingresamos los datos a modificar
        for i in range(1):
            #Usamos diccionario para establecer datos especificos y orden del usuario
            usr_prototype = {
                'Nombres'  : '',
                'Apellidos': '',
                'Edad'     : '',
                'Cedula'   : ''
            }
            usr_prototype['Nombres'] = input("Nombres: ")
            usr_prototype['Apellidos'] = input("Apellidos: ")
            usr_prototype['Edad'] = int(input("Edad: "))
            usr_prototype['Cedula'] = int(input("Cédula: "))
            #Antes de proceder a guardar el usuario se validará la cédula. Es una llave única de cada usuario
            self.listaUsers2.append(usr_prototype)
            result = any(i == j for i, j in zip(self.listaUsers, self.listaUsers2))
            
            if result:
                modificar_listas = modificar_items(self.listaUsers, self.listaUsers[:], self.listaUsers2)
                self.mostrar_datos_usuario(usr_prototype["Cedula"])
            else:
                print("no")

mostrar_datos_usuario方法

def mostrar_datos_usuario(self, ced):
        user_found = False
        for i in self.listaUsers:
            if i["Cedula"] == ced:
                for key, value in i.items():
                    print(f"{key}: {value}")
                    user_found = True
                break   

modificar_items函数

def modificar_items(lista, valores_actuales=[], valores_nuevos=[]):
       for i, sublista, in enumerate(lista):
           if all(item_act is None or item_act == item_list
                  for item_list, item_act in zip(sublista, valores_actuales)):
               for j, item_nuevo in enumerate(valores_nuevos):
                   if item_nuevo is not None:
                       lista[i][j] = item_nuevo

问题分析

  1. modificar_items函数逻辑错误:该函数把字典当成列表处理(通过enumerate遍历字典的键),无法正确更新用户字典中的字段值。
  2. Cedula验证逻辑失效:result = any(i == j for i, j in zip(self.listaUsers, self.listaUsers2))仅对比两个列表对应位置的元素是否相等,完全未实现“新Cedula是否被其他用户占用”的验证。
  3. 代码冗余与逻辑混乱:for i in range(1)无实际意义;找到用户后未终止后续流程,导致用户不存在时仍会执行更新输入逻辑。
  4. 缺乏输入合法性校验:未处理年龄输入非数字、Cedula输入非数字等异常情况。

修正后的代码

优化后的actualizar_datos_usuario方法

def actualizar_datos_usuario(self):
        clear()
        # 查找并展示目标用户
        try:
            ced = int(input("Ingrese la cédula del usuario a actualizar: "))
        except ValueError:
            print("Cédula必须是数字,请重新输入。")
            return
        
        target_user = None
        for user in self.listaUsers:
            if user["Cedula"] == ced:
                target_user = user
                print("当前用户信息:")
                for key, value in user.items():
                    print(f"{key}: {value}")
                break
        
        if not target_user:
            print("Cédula未注册。")
            return
        
        print("\n\n[更新用户信息]\n")
        # 收集新信息,默认保留原字段值
        new_data = {
            'Nombres': input(f"Nombres(当前:{target_user['Nombres']}):") or target_user['Nombres'],
            'Apellidos': input(f"Apellidos(当前:{target_user['Apellidos']}):") or target_user['Apellidos'],
            'Edad': target_user['Edad']
        }
        
        # 处理年龄输入校验
        try:
            edad_input = input(f"Edad(当前:{target_user['Edad']}):")
            if edad_input:
                new_edad = int(edad_input)
                if new_edad <= 0:
                    raise ValueError("年龄必须为正整数")
                new_data['Edad'] = new_edad
        except ValueError as e:
            print(f"年龄输入错误:{e},将保留原年龄。")
        
        # 处理Cedula修改与唯一性验证
        new_ced_input = input(f"Cédula(当前:{target_user['Cedula']},留空则不修改):")
        if new_ced_input:
            try:
                new_ced = int(new_ced_input)
                # 验证新Cedula是否被其他用户占用
                for user in self.listaUsers:
                    if user["Cedula"] == new_ced and user is not target_user:
                        print("该Cédula已被其他用户占用,无法修改。")
                        return
                new_data['Cedula'] = new_ced
            except ValueError:
                print("Cédula必须是数字,将保留原Cédula。")
        else:
            new_data['Cedula'] = target_user['Cedula']
        
        # 更新用户数据
        target_user.update(new_data)
        print("\n用户信息更新成功!更新后信息:")
        self.mostrar_datos_usuario(new_data['Cedula'])

简化说明

原modificar_items函数逻辑不适用于字典结构,可直接使用Python字典内置的update()方法完成字段更新,无需额外编写该函数。

改进建议与技巧

  • 用字典映射替代列表存储用户:将listaUsers改成以Cedula为键的字典(如self.users = {ced: user_dict, ...}),查找、更新用户的时间复杂度从O(n)降到O(1),代码更简洁:
    # 示例:快速查找用户
    target_user = self.users.get(ced)
    
  • 封装通用方法:把“查找用户”“验证Cedula唯一性”等逻辑封装成独立方法,避免重复代码,比如:
    def buscar_usuario_por_cedula(self, ced):
        for user in self.listaUsers:
            if user["Cedula"] == ced:
                return user
        return None
    
    def es_cedula_disponible(self, ced, exclude_ced=None):
        for user in self.listaUsers:
            if user["Cedula"] == ced and user["Cedula"] != exclude_ced:
                return False
        return True
    
  • 加强输入验证:对所有用户输入做合法性校验,比如Cedula不能为负数、年龄需在合理范围(如1-120)等,用try-except捕获输入异常。
  • 分离业务与交互:把数据处理逻辑(如更新用户)和用户交互逻辑(如输入输出)分开,便于单元测试和代码维护。
  • 避免可变默认参数:原modificar_items函数的valores_actuales=[]属于可变默认参数,会导致多次调用时参数值累积,应改为valores_actuales=None,再在函数内初始化。

内容的提问来源于stack exchange,提问作者2Sawarasa2

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 22:54:57