【问题标题】:Python read next line from what the user inputsPython 从用户输入的内容中读取下一行
【发布时间】:2015-10-17 21:07:42
【问题描述】:

所以基本上我有一个程序,它可以在文档中创建用户名和密码,并搜索与使用该程序的人输入的用户名一起使用的密码。

例如: 程序要求我输入我输入的用户名:'13'。 文本文档中的 13 以下是“sadfsdfsdf”。 我希望程序跳到“用户名:1​​3”下方并读取并打印“密码:sadfsdfsdf”。

请注意,我在 .txt 文件中有多个用户名和密码

u = '用户名:'

提前致谢!

def SearchRecordProgram():
    while True:
                    user_search = input("Please enter the username you wish to see the password for: ")
                    full_user = u + user_search
                    if full_user in open('User_Details.txt').read():
                            print(" ")
                            print ("Username found in our records")
                            print(" ")
                            print(full_user)
                            break
                    else:
                            print("Username entered does not match our records")

【问题讨论】:

  • 请说这是一个练习,不是为了正确使用的东西?
  • 不,我只是想掌握python
  • 好的,呸!如果您以专业的方式存储密码,则不是存储密码的方式:P
  • 变量u从何而来?
  • 另外,请告诉我您不想在每次搜索时重新加载整个文件(顺便说一句,不关闭它)

标签: python


【解决方案1】:

所以,想象你的文件是这样的:

Username : 13
Password : sadfsdfsdf
Username : 15
Password : Lalalala

你可以像这样解析它(使用正则表达式):

import re  #  regular expression module
regex = re.compile("Username :(.*)\nPassword :(.*)")

# read text from file
with open(filePath,'r') as f:
    text = f.read() 

u_pass = regex.findall(text)
# [(' 13', ' sadfsdfsdf'), (' 15', ' Lalalala')]

user_dict = {u:password for u,password in u_pass}
#  {' 13': ' sadfsdfsdf', ' 15': ' Lalalala'}

现在您可以通过询问该用户的密码来获取该用户的密码:

# given username and password_input

if username in user_dict and user_dict[username] == password_input:
# if username exists and password okay
    print "Authentication succeeded."

【讨论】:

    【解决方案2】:

    当你想打开一个文件时,你几乎应该总是使用with 语句:

    with open('User_Details.txt') as read_file:
        # Do reading etc. with `read_file` variable
    

    这将确保正确处理任何错误并且文件不会保持打开状态。

    现在文件已打开,我们需要遍历每一行,直到找到与我们的用户名匹配的行。我希望你知道for loop 的工作原理:

    username = 'Username: 13'  # Get this however you want
    with open('User_Details.txt') as read_file:
        for line in read_file:
            line = line.strip()  # Removes any unnecessary whitespace characters
            if line == username:
                # We found the user! Next line is password
    

    我们需要获取包含密码的下一行。有很多方法可以获取下一行,但一种简单的方法是使用 next() 函数,它简单地从可迭代对象中获取下一个元素(在本例中为文件中的下一行):

    username = 'Username: 13'
    with open('User_Details.txt') as read_file:
        for line in read_file:
            line = line.strip()
            if line == username:
                password = next(read_file)
                break  # Ends the for loop, no need to go through more lines
    

    现在您有了密码和用户名,您可以对它们做任何您想做的事情。将输入和输出置于程序逻辑之外通常是个好主意,因此不要直接在 for 循环内打印密码,而是直接在此处接收密码,然后在外部打印。

    你甚至可能想把整个搜索逻辑变成一个函数:

    def find_next_line(file_handle, line):
        """Finds the next line from a file."""
        for l in file_handle:
            l = l.strip()
            if l == line:
                return next(file_handle)
    
    
    def main():
        username = input("Please enter the username you wish to see the password for: ")
        username = 'Username: ' + username
        with open('User_Details.txt') as read_file:
            password = find_next_line(read_file, username)
        password = password[len('Password: '):]
        print("Password '{0}' found for username '{1}'".format(password, username))
    
    if __name__ == '__main__':
        main()
    

    最后,以这种格式存储任何东西绝对是疯狂的(更不用说密码安全的东西,但我知道你只是在学习东西),为什么不这样做:

    username:password
    markus:MarkusIsHappy123
    BOB:BOB'S PASSWORD
    

    这可以很容易地转换成字典:

    with open('User_Details.txt') as read_file:
        user_details = dict(line.strip().split(':') for line in read_file)
    

    现在要获取用户名的密码,您可以:

    username = input('Username: ')
    if username in user_details:
        print('Password:', user_details[username])
    else:
        print('Unknown user')
    

    【讨论】:

    • 请你把它放到一个代码块中,注意安全不是这个项目的问题
    • @NodeMN 所以你问我是否可以为你做整个程序?我可以提供帮助,但 SO 不是代码编写服务。另外,我已经给你写好了代码,剩下的你应该可以做......
    • @NodeMN 有什么特别不明白的地方吗?
    • 不,它只是知道放置它的顺序。我是 python 新手。
    • ValueError: 字典更新序列元素 #2 的长度为 1; 2 是必需的
    【解决方案3】:

    也许不是美女,但这样的事情会起作用:

    with open(users_file, "r") as f:
        lines = f.read()
    
    def get_password(user_id):
        entries = iter(lines.splitlines())
        for entry in entries:
            if(entry.startswith("{}:{}".format(prefix, user_id))):
                return next(entries)
    
    print "Password:", get_password("13")
    

    【讨论】:

      【解决方案4】:
      def SearchRecordProgram():
          while True:
              user_search = input("Please enter the username > ")
      
              file = open('User_Details.txt')
              usernames = file.readlines()  # Read file into list
              file.close()
      
              if user_search in usernames: # Username exists
                  print ('Found Username')
                  password = usernames[usernames.index(user_search)+1]
                  print ('Password is: ' + password)   
      
                  break  # Exit loop
      
               else:  # Username doesn't exist
                   print("Username entered does not match our records")
      

      请注意,如果密码恰好是用户名,这将不起作用,例如:

      user1
      password1
      user2
      user3  # This is the password for user3
      user3
      password3
      

      如果您搜索“user3”,此代码将输出“user3”作为“user3”的密码,因为它会找到“user3”的第一个实例(第 4 行),然后查找下一行(第 5 行),这是下一个用户名。

      更糟糕的是,如果“user3”是文件中的最后一行,它会以错误结束,因为没有更多的行。您可以使用以下代码添加检查找到的用户名的索引是否为偶数(即索引 0、2、4、8):

      if not usernames.index(user_search) % 2:  # Checks the remainder after / by 2.
                                                # If it's 0 then it's an even index.
          password = usernames[usernames.index(user_search)+1]
          print ('Password is: ' + password)   
      

      但如果发生这种情况,您无能为力。

      但是,您可以将用户名文件操作为只有这样的用户名:

      lst = [0, 1, 2, 3, 4, 5, 6, 7]
      print (lst[0::2])
      

      打印出来的

      [0, 2, 4, 6]
      

      所以代码可以改成这样:

      def SearchRecordProgram():
          while True:
              user_search = input("Please enter the username > ")
      
              usernames = open('User_Details.txt').readlines()  # Read file into list
      
              if user_search in usernames[0::2]: # Username exists
                  print ('Found Username')
                  password = usernames[1::2][usernames[0::2]].index(user_search)]
                  print ('Password is: ' + password)   
      
                  break  # Exit loop
      
               else:  # Username doesn't exist
                   print("Username entered does not match our records")
      

      这里是一个细分

      password = usernames[1::2]  # Gets the odd items (passwords)
                                [  # Get index item. The index returned from searching
                                   # the usernames will be the same as the index needed
                                   # for the password, as looking at just the odd items:
                                   # [0, 2, 4, 6]
                                   # [1, 3, 5, 7] - even has the same index as next odd.
                                 usernames[0::2] # Gets even items (usernames)
                                                ].index(user_search)]
                                                # Only searches the usernames. This
                                                # means passwords being the same is not
                                                # an issue - it doesn't search them
      

      【讨论】:

      • 这会使文件保持打开状态并将整个文件存储到内存中(这可能不是问题,但无论如何都可以轻松避免)。
      猜你喜欢
      • 2011-10-21
      • 2023-01-27
      • 1970-01-01
      • 2020-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-17
      • 1970-01-01
      相关资源
      最近更新 更多