Python中while循环执行后with语句被跳过是什么原因?
问题原因
两个核心逻辑错误直接导致你遇到的现象:
- 密码校验循环的初始条件错误:你将循环控制变量
pass_matches初始赋值为None,但循环的进入条件写的是while pass_matches is False:。Python中None和False是完全不同的对象,None is False的判断结果为False,因此这个密码输入校验的循环从一开始就不会执行,整个密码校验块直接被跳过,代码跑完外层分支后自然回到最外层的主循环,重新弹出初始询问。 - 文件读取逻辑存在冗余错误:你在第二个打开
users.txt的代码块中,先调用f.read()将整个文件内容全部读入内存,此时文件指针已经移动到文件末尾,后续写的f.seek()操作完全是多余的——你是从内存中的字符串readfile里查找的用户名索引位置,这个偏移是字符串的字符位置,直接对文件对象做seek不仅没有必要,还很容易因为换行、编码等问题读错位置,拿不到正确的密码哈希。
修复方案
- 将
pass_matches的初始值从None改为False,保证密码校验循环可以正常进入。 - 移除无效的文件指针seek操作,直接从已经加载到内存的文件内容字符串中提取对应位置的密码哈希,避免文件指针偏移错误。
修复后的完整代码如下:
import hashlib while True: have_account = input("do you have your details stored here already? y/n ") while have_account not in ("y", "n"): print("please type either y or n") have_account = input("y/n ") if have_account == "y": username_exists = False while username_exists is False: username_login = input("Please enter a username ") with open("users.txt", "r") as f: readfile = f.read() if username_login in readfile: username_exists = True print("debug: username_exists is " + str(username_exists)) else: username_exists = False print("That user does not exist") print("debug: I ran this command") with open("users.txt", "r") as f: readfile = f.read() user_loc = readfile.index(username_login) user_len = len(username_login) # 直接从内存字符串中切片取哈希,移除无效的seek操作 pass_hash = readfile[user_loc + user_len + 3 : user_loc + user_len + 3 + 64] password_login_hashed = None # 修正循环初始值,保证可以进入密码校验流程 pass_matches = False while pass_matches is False: password_login = input("Please enter your password ") password_login_hashed = hashlib.sha256(password_login.encode('utf-8')).hexdigest() password_login = None if password_login_hashed == pass_hash: pass_matches = True print("Congrats! You logged in!") else: pass_matches = False quit_question = input("Incorrect password! Please try again or type \"quit\" to quit") if quit_question == "quit": quit()
注意:上述代码默认你的
users.txt存储格式为用户名<3个分隔字符>64位sha256哈希值,如果你的实际存储分隔符长度不是3,对应调整切片的偏移量即可。
内容的提问来源于stack exchange,提问作者Neoxr
相关产品推荐
相关产品推荐

