繁体   English   中英

只读取文件python的最后一行

[英]Only reads last line of file python

我正在尝试为基于文本的基本解决方案创建登录注册系统

注册系统工作正常,但尝试登录时,即使输入的用户名和密码正确,它也仅接受外部文件最后一行的用户名和密码。 我不确定是什么问题,因为仅接受文件的最后一行。 谢谢您的帮助!

def loginSys():
    ("=========LOGIN=========")
    f = open("loginDetails.txt","r")
    for line in open("loginDetails.txt","r").readlines():
        loginInfoP1 = line.split()
    print("Player One, enter your details first!")
    correctDetailsP1 = 0
    while correctDetailsP1 == 0:
        usnmAttemptP1 = input("Enter your username\n")
        pswdAttemptP1 = input("Enter your password\n")
        if usnmAttemptP1 == loginInfoP1[0] and pswdAttemptP1 == loginInfoP1[1]:
            correctDetailsP1 += 1
            print("You have successfully logged on " + usnmAttemptP1 + "!")
        else:
            print("Either your username or password is incorrect! Please try again")
    f.close()  
    x = open("loginDetails.txt","r")
    for line in open("loginDetails.txt","r").readlines():
        loginInfoP2 = line.split()
        #print(loginInfoP2)
    print("Player Two, enter your details now!")
    correctDetailsP2 = 0
    while correctDetailsP2 == 0:
        usnmAttemptP2 = input("Enter your username\n")
        pswdAttemptP2 = input("Enter your password\n")
        if usnmAttemptP2 == loginInfoP2[0] and pswdAttemptP2 == loginInfoP2[1]:
            correctDetailsP2 += 1
            print("You have successfully logged on " + usnmAttemptP2 + "!")
        else:
            print("Either your username or password is incorrect! Please try again")
    x.close()
    startGame()

谢谢

再看看这里发生了什么:

f = open("loginDetails.txt","r")
for line in open("loginDetails.txt","r").readlines():
    loginInfoP1 = line.split()

您正在打开文本文件,然后遍历其所有行。 对于每一行,您都将其内容放在loginInfoP1 对于每一行

这意味着在for循环之后, loginInfoP1的内容loginInfoP1将是最后一个迭代行,即文件的最后一行。


如果这些行遵循一定的顺序,即第一行是播放器1的凭据,第二行是播放器2的凭据; 然后您可以返回一个generator( yield )并按需迭代这些行:

def get_login_information(file):
    with open(file, 'r') as fh:
        for line in fh:
            yield line.split()

def loginSys():
    login_information = get_login_information('loginDetails.txt')

    print("=========LOGIN=========")
    print("Player One, enter your details first!")

    loginInfoP1 = next(login_information) # <------

    correctDetailsP1 = 0
    while correctDetailsP1 == 0:
        usnmAttemptP1 = input("Enter your username\n")
        pswdAttemptP1 = input("Enter your password\n")
        if usnmAttemptP1 == loginInfoP1[0] and pswdAttemptP1 == loginInfoP1[1]:
            correctDetailsP1 += 1
            print("You have successfully logged on " + usnmAttemptP1 + "!")
        else:
            print("Either your username or password is incorrect! Please try again")

    print("Player Two, enter your details now!")

    loginInfoP2 = next(login_information) # <------

    correctDetailsP2 = 0
    while correctDetailsP2 == 0:
        usnmAttemptP2 = input("Enter your username\n")
        pswdAttemptP2 = input("Enter your password\n")
        if usnmAttemptP2 == loginInfoP2[0] and pswdAttemptP2 == loginInfoP2[1]:
            correctDetailsP2 += 1
            print("You have successfully logged on " + usnmAttemptP2 + "!")
        else:
            print("Either your username or password is incorrect! Please try again")

    startGame()

这里:

for line in open("loginDetails.txt","r").readlines():
    loginInfoP1 = line.split()
# code using loginInfoP1 here

您要遍历文件的内容,并在每次迭代时重新绑定loginInfoP1显然,一旦for循环结束, loginInfoP1包含最后一行的值。

您想要的是根据整个登录数据(使用用户名作为密钥)构建一个字典:

accounts = {}
# NB : make sure we close the file after use
with open("loginDetails.txt") as f:
    # nb: files are iterable, no need to read the whole
    # file at once
    for line in f: 
        # make sure we don't have an empty line
        line = line.strip()
        if not line:
            continue
        username, passwd = line.split()
        accounts[username] = passwd

那么您只需要检查dict:

    usnmAttemptP1 = input("Enter your username\n").strip()
    pswdAttemptP1 = input("Enter your password\n").strip()
    if  usnmAttemptP1 in accounts and accounts[usnmAttemptP1] == pswdAttemptP1:
        # ok

请注意,两个玩家的“登录”代码完全相同,因此您可以在专用功能中对其进行重构。 另外,您的执行流程是错误的-登录功能与开始游戏没有关系,它应该仅向其调用者返回一些值(用户的帐户详细信息或仅指示用户正确登录的布尔值),并让调用者随身携带进行下一步:

def read_accounts():
    accounts = {}
    # NB : make sure we close the file after use
    with open("loginDetails.txt") as f:
        # nb: files are iterable, no need to read the whole
        # file at once
        for line in f: 
            # make sure we don't have an empty line
            line = line.strip()
            if not line:
                continue
            username, passwd = line.split()
            accounts[username] = passwd
    return accounts


def auth_user(accounts, prompt):
    print(prompt)
    max_attempts = 10 # let's not loop forever
    correctDetailsP1 = 0
    while correctDetailsP1 < max_attemps:
        usnmAttemptP1 = input("Enter your username\n")
        pswdAttemptP1 = input("Enter your password\n")
        if  usnmAttemptP1 in accounts and accounts[usnmAttemptP1] == pswdAttemptP1:

            correctDetailsP1 += 1
            print("You have successfully logged on " + usnmAttemptP1 + "!")
            return True
        else:
            print("Either your username or password is incorrect! Please try again")
    # failed
    return False



def main():
    accounts = read_accounts()
    for prompt in ("Player One, enter your details first!", "Player Two, enter your details now!"):
        if not auth_user(accounts, prompt):
            return False
     startGame() 

if __name__ == "__main__":
    main()            

附带说明:我了解这不是关键任务软件,但是存储未加密的密码是一个非常糟糕的主意。 规范的方法是存储加密的密码,并在登录时对用户提供的密码进行加密(当然使用相同的算法),并将其与存储的加密密码进行比较。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM