只读取文件python的最后一行

问题描述 投票:0回答:2

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

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

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()

谢谢

python file username
2个回答
0
投票

再看一下这里发生的事情:

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

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

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


如果这些行遵循某个顺序,即第一行是玩家1的凭证,第二行是玩家2的凭证;那么你可以返回一个生成器(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()

0
投票

这里:

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

你正在迭代文件的内容并在每次迭代时重新绑定loginInfoP1 - 所以很明显,一旦for循环结束,loginInfoP1就会包含最后一行的值。

你想要的是从整个登录数据构建一个dict(使用用户名作为密钥):

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

然后你只需检查字典:

    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()            

作为旁注:我知道这不是关键任务软件,但存储未加密的密码是一个非常糟糕的主意。规范的方法是存储加密的密码,并在登录时加密用户给出的密码(当然使用相同的算法)并将其与存储的加密密码进行比较。

© www.soinside.com 2019 - 2024. All rights reserved.