2017-11-18 98 views
0

就我而言,我正在创建一个注册表,并且需要通过使用CSV将登录凭据存储到外部文件中。如何在Python中使用CSV读取所有行?

我有2个问题:

  1. 每次登录(用户名和密码),除了第一个不 工作。我第一次登录“14JeoJun”的用户名和“海鸥” 作品,但下一个“13ParJim”的用户名和“excuseme” 密码不对,还有休息之后。我认为这是因为它没有读取所有的行。
  2. 它不会循环3次代码,然后关闭。它会永远循环它,如果你一直搞错了,即使登录凭证不是第一个但是是正确的。如果第一个登录凭证是正确的,则停止循环并退出。我认为这是因为上面的第一个问题。

    with open("login_credential.txt","r") as login_credential: 
    for x in range (0,2): 
        inputted_username = input("Please enter your username - ") 
        inputted_password = input("Please enter your password - ") 
        login_credentialReader = csv.DictReader(login_credential) 
        for lines in login_credentialReader: 
          if lines["username"].lower() == inputted_username and lines["password"].lower() == inputted_password: 
           print("Welcome...") 
           sys.exit() 
          elif lines["username"].lower() != inputted_username or lines["password"].lower() != inputted_password: 
           x += 1 
           print("Login credentials are incorrect. Please try again.") 
           login() 
        if x >= 3: 
         print("Too many incorrect tries...") 
         sys.exit 
    

这是在我的外部文件(login_credential.txt):

用户名,密码,名,姓,一年
14JeoJun,海鸥,Jungkook,全度妍2014
13ParJim,excuseme,济民,公园,2013
10KimNam,gotjams,Namjoon,金,2010

每当我先切换,只有第一个会起作用。

+0

读取csv文件是这样一个标准问题;你为什么不使用熊猫,这将更容易处理数据,因为你可以以矢量化的方式处理所有这些循环? – Magellan88

+0

@ Magellan88它看起来像是学校作业 – Gnudiff

回答

0

读取一次文件后,文件句柄关闭,您不能再读取它。特别是,看看这里:

with open("login_credential.txt","r") as login_credential: 
    for x in range (0,2): 
     inputted_username = input("Please enter your username - ") 
     inputted_password = input("Please enter your password - ") 
     login_credentialReader = csv.DictReader(login_credential) 
     for lines in login_credentialReader: 
      # ... 

     # ... 

for x in range(...)循环的第二次迭代, 文件句柄login_credential已充分阅读, 就不会再重读, 所以身体内部for循环的执行不会被执行。

此代码还存在其他严重问题。 例如,在for x in range(...)循环中, 不应在循环体内修改x的值。 它可能无法按预期工作,因为在下一次迭代中x将重置为来自range(...)的下一个值。不要这样做。

一个小问题,看在这些条件下:

if lines["username"].lower() == inputted_username and lines["password"].lower() == inputted_password: 
    # ... 
elif lines["username"].lower() != inputted_username or lines["password"].lower() != inputted_password: 
    # ... 

第二个条件是所述第一相反。 这是没有意义的,你可以用一个简单的else替换长的elif


按照一般的做法, 而不是重新读取用户, 它可能是更好的读取文件的线只有一次的用户名/密码的每次重试密码文件,以及重用它。 这将需要更多的内存,但保存在I/O上。 这可能是一个很好的折衷。

它可能是这样的:

with open("login_credential.txt","r") as login_credential: 
    login_credentialReader = csv.DictReader(login_credential) 
    lines = [line for line in login_credentialReader] 

for x in range(2): 
    inputted_username = input("Please enter your username - ") 
    inputted_password = input("Please enter your password - ") 

    # ... 
+0

虽然这本身就是一个很好的答案,但我认为它确实太多了,因为提供完整的学校作业代码解决方案并不符合学生的最佳利益(谁似乎在时刻与他自己的代码的基本理解斗争),根据常见问题https://meta.stackoverflow.com/questions/334822/how-do-i-ask-and-answer-homework-questions – Gnudiff

+1

@Gnudiff我同意你的意图,但我不确定我放弃了太多。我认为这是主观的。但是我接受了您的建议并重写了答案,做了更多的解释并在银盘上交出了更少的代码。 – janos

0

你在做什么目前正在检查每一行,如果匹配,如果它没有。

需要要做的只是检查一行,如果匹配,如果不匹配 - 尝试下一行。只有在文件中没有行匹配的情况下,你需要说出错误的凭据 - 该行在循环之后。