Python读取JSON文件登录验证报错求助:TypeError: unhashable type: 'list'
问题排查与修复方案
核心错误原因
- 字典访问语法错误:你在循环里用
item[read_file]["email"]完全错误。read_file是整个用户列表(list类型),不能作为字典的键,这直接导致TypeError: unhashable type: 'list'。正确方式是直接访问字典元素item["email"],因为item就是列表中的单个用户字典。 - JSON键大小写不统一:
users.json里存在大小写不一致的键,比如有的是password,有的是Password;有的是role,有的是Role,这会导致密码或角色匹配失败。 - 登录成功后变量引用错误:打印欢迎信息时错误使用
read_file[read_file]["email"],应该用当前匹配的item对象属性。 - 时间获取逻辑错误:
clock只在程序启动时获取一次,登录成功时显示的是程序启动时间,而非实际登录时间。 - 失败计数逻辑错误:当前代码每次输入都会累加
count,无论登录成功与否,不符合需求。
修复后的完整代码
首先统一JSON文件的键为小写(推荐做法,避免大小写问题),修改后的users.json:
[{"email": "Mark", "password": "Hi123", "role": "Owner"},{"email": "Elsje", "password": "Hi123", "role": "Family member"},{"email": "Fred", "password": "Hi123", "role": "Owner"}]
修正后的Python代码:
import json import time count = 0 # 初始化失败登录尝试次数为0 def open_file(filename): # 定义读取文件的函数 with open(filename) as json_file: return json.load(json_file) read_file = open_file("users.json") while True: email = input("\nEnter your username: ") password_input = input("Enter your password: ") login_success = False print("") for user in read_file: # 直接访问字典的键,匹配输入的邮箱和密码 if user["email"] == email and user["password"] == password_input: # 登录成功时获取当前时间 current_time = time.localtime() clock = time.strftime("%I:%M:%S %p", current_time) print(f"Welcome {user['email']} ({user['role']}), you successfully logged in at {clock}\n") count = 0 # 重置失败次数 login_success = True break # 找到匹配用户后退出循环 if login_success: break else: count += 1 # 只有登录失败时累加计数 print("Incorrect E-mail or password!\n") if count >= 5: # 失败次数达到5次则锁定 current_time = time.localtime() clock = time.strftime("%I:%M:%S %p", current_time) print(f"On {clock} You have logged incorrectly 5 times. You are blocked for 15 minutes!") time.sleep(900) break
关键修复点说明
- 循环中把
item[read_file]["email"]改为user["email"],直接访问字典属性。 - 统一JSON文件的键为小写,确保代码访问的键与JSON一致。
- 登录成功时才获取当前时间,保证显示实际登录时间。
- 调整失败计数逻辑,仅登录失败时增加
count,成功时重置为0。 - 找到匹配用户后用
break退出循环,避免不必要的遍历。
内容的提问来源于stack exchange,提问作者DanielDude
相关产品推荐
相关产品推荐

