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

无法用pickle保存对象列表导致后续用户登录失败问题求助

问题排查与修复

核心问题:类型不匹配导致验证失败

从你打印的user_list可以看到,用户的username是整数类型(比如username : 1),而登录时传入的username参数如果是字符串类型(比如用户输入的"1"),或者反过来,就会出现类型不匹配的问题。在原判断条件str(u.username) == username中,str(u.username)会把整数转成字符串,但如果username是整数,就会触发字符串与整数直接比较(比如"1" == 1),结果必然为False,导致验证失败。

同理,如果password也存在类型不一致的情况,同样会让验证条件不成立。

其他潜在问题

  1. 保存函数缩进错误:try:语句的缩进比函数体多了一层,这会直接引发IndentationError,导致函数无法执行,需要修正缩进。
  2. 过于宽泛的异常捕获:原代码except:会捕获所有异常(包括语法错误、内存错误等),可能导致未知问题被隐藏,应该只捕获文件不存在和反序列化失败的特定异常。
  3. 多余的序列化方法:__getstate__和__setstate__是多余的,pickle默认会序列化对象的__dict__,手动实现反而可能引入潜在问题。

修复方案

1. 修正登录验证的类型匹配问题

将判断条件改为两边都转成字符串后再比较,彻底避免类型不匹配:

for u in user_list:
    # 统一转成字符串后比较,确保类型一致
    if str(u.username) == str(username) and str(u.get_password()) == str(password):
        print("Login successful...")
        # 找到匹配用户后建议返回该对象或跳出循环,避免无效遍历
        return u
# 遍历结束未找到匹配,提示登录失败
print("Login failed: username or password incorrect")
return None

2. 修正保存函数的缩进与异常捕获

def save_to_file(file_path, user):
    # Writing to a file
    try:
        with open(file_path, "rb") as file:
            user_list: list = pickle.load(file)
        user_list.append(user)
        with open(file_path, "wb") as file:
            pickle.dump(user_list, file)  # 无需生成新列表,直接dump原列表即可
    except (FileNotFoundError, pickle.UnpicklingError):  # 仅捕获特定异常
        with open(file_path, "wb") as file:
            pickle.dump([user], file)

3. 可选:删除User类中多余方法

删除__getstate__和__setstate__,让pickle默认处理序列化:

class User:
    """
    This class implements a user model
    that can login and register
    it dumps data to pickle file
    """

    def __init__(
            self, name: str, username: str, password: str, phone: str, balance: int, email: str = None,
    ) -> None:
        self.name: str = name
        self.username: str = username
        self.__password: str = password
        self.phone: str = phone
        self.balance: int = balance
        self.email: str = email

    def get_password(self) -> str:
        return self.__password

    def withdraw(self, amount) -> None:
        if self.balance > amount:
            self.balance -= amount
        else:
            print('Not Enough Balance Available')

    def deposit(self, amount) -> None:
        self.balance += amount

    def set_password(self, password) -> None:
        self.__password = password

    def show_balance(self) -> int:
        return self.balance

验证建议

  1. 登录时打印type(username)和type(u.username),确认两者类型是否一致。
  2. 打印str(u.username), username, str(u.get_password()), password的具体值,直观查看比较双方的内容差异。

内容的提问来源于stack exchange,提问作者Setare Kalantari

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 13:35:59