在文本文件Python中编辑密码的最简单方法

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

我有以下代码,它贯穿逐行读取文件的阶段,将其转换为列表,编辑该列表中的字段,但最后一个阶段是重写原始文件,包含此编辑。

我会对建议最简单/最简单的修复(不使用pandas / numpy等)和使用提供的原始代码的答案感兴趣。

我当前的算法包括必须创建一个包含所有记录的新文件,但链接到该用户名的记录除外,然后在此列表中写入。这看似艰巨而且没必要。任何解决方案都感激不尽!

评论中更清楚地解释了这项任务:

 """ ==============TASK
    ALLOW THE USER TO CHANGE OR EDIT THEIR PASSWORD
    1. Search for any given username
    2. Edit the password field for that given username
    3. Save the new updated username and password to file / updated
    """

    import csv
    def main():
        #1. This code snippet asks the user for a username and then allows them to change password for that record
        updatedlist=[]
        with open("fakefacebook.txt",newline="") as f:
          reader=csv.reader(f)
          print("CHANGE PASSWORD?!")
          username=input("Enter the username for the required user:")
          for row in reader: #for every row in the file
              for field in row:

                    if field==username: #if a field is == to the required username
                        updatedlist.append(row) #add each row, line by line, into a list called 'udpatedlist'
                        newpassword=input("Enter new password")
                        #print(updatedlist[0][1]) (this is how we get at the password field, noting it is a nested list)
                        updatedlist[0][1] = newpassword #set the field for password to the new password


          updatepassword(updatedlist)

    def updatepassword(updatedlist):
        with open("fakefacebook.txt","w",newline="") as f:
            Writer=csv.writer(f)
            Writer.writerows(updatedlist)
            print("File has been updated")


    main()

注意:此时代码只允许用户更改密码(这在列表中已更改)。该列表仅包含该用户的记录。它会将此单个记录(使用更改的密码)覆盖到文本文件,而不是所需的内容(原始文件内容+仅此编辑)

文件内容

username,password,email,no_of_likes
marvR,pass123,[email protected],400
smithC,open123,[email protected],200
blogsJ,2bg123,[email protected],99

要求的输出

如果测试使用:marvR将密码更改为:boo123

新文件应包含:

username,password,email,no_of_likes
marvR,**boo123**,[email protected],400
smithC,open123,[email protected],200
blogsJ,2bg123,[email protected],99

任何有关为初学者教学的最佳方法的评论/解释也将受到赞赏。奇怪的是Python没有开发某种类型的模块来使文件中的字段编辑比这个3步算法更容易,对于初学者(我说的是13-14岁的孩子)来说,这对于锻炼来说真是太艰难了

python-3.x csv edit
3个回答
1
投票

@ VPfB的答案也应该考虑在内。

这只是更新记录而不替换文件中现有记录的答案。但是有更好的方法可以做到这一点。

import csv

def main():
    #1. This code snippet asks the user for a username and then allows them to change password for that record
    updated_list = []
    cached_list = []

    with open("fakefacebook.txt", newline="") as f:
        reader = list(csv.reader(f)) # Convert iterable to list to make things easier.
        print("CHANGE PASSWORD?!")
        username=input("Enter the username for the required user: ")
        cached_list = reader # store copy of data.

        for row in reader: #for every row in the file
            for field in row:  
                if field == username: #if a field is == to the required username
                    updated_list.append(row) #add each row, line by line, into a list called 'udpated_list'
                    newpassword = input("Enter new password: ")
                    #print(updatedlist[0][1]) (this is how we get at the password field, noting it is a nested list)
                    updated_list[0][1] = newpassword #set the field for password to the new password

        update_password(updated_list, cached_list)

def update_password(updated_list, cached_list):
    for index, row in enumerate(cached_list):
        for field in row:
            if field == updated_list[0]:
                cached_list[index] = updated_list # Replace old record with updated record.

    with open("fakefacebook.txt","w", newline="") as f:
        Writer=csv.writer(f)
        Writer.writerows(cached_list)
        print("File has been updated")


main()

3
投票

迄今尚未解决其中一个相关问题。您已经提到过“教学初学者”,所以请将此答案视为其他答案的补充。

编辑密码文件等文件时,不应像在此处显示的代码中那样覆盖原始文件。如果写入由于任何原因(包括磁盘已满或断电)而失败,则可能会丢失数据。更重要的是,文件应始终处于一致状态,即任何人都不应该看到部分写入的文件。

为此:

  1. 从文件中读取数据
  2. 在内存中修改它 根据需要处理数据
  3. 将结果保存到一个新的临时文件,关闭该文件(with自动执行),你甚至可能想调用os.fsync()
  4. 如果有任何错误,请删除临时文件并在此处停止
  5. 只有在一切都很好的情况下,才能使用os.replace()(Python 3.3+)将临时文件原子重命名为原始文件。原子操作只需一步即可完成。

更新:修改了updatepassword代码并附带一些注释:

FILE = "fakefacebook.txt"

def updatepassword(updatedlist):
    # create the tempfile in the same directory (os.replace requires the same filesystem)
    tempfile = FILE + ".tmp"
    try:
        # "x" = fail with the FileExistsError if the file exists already
        with open(tempfile, "x", newline="") as f:
            writer = csv.writer(f)
            writer.writerows(updatedlist)
            f.flush()               # flush the internal buffers
            os.fsync(f.fileno())    # write to disk
        os.replace(tempfile, FILE)
        print("File has been updated")
        tempfile = None     # tempfile renamed
    except FileExistsError:
        print("Another copy is running or stale tempfile exists")
        tempfile = None     # tempfile does not belong to this process
    except OSError as err:
        print("Error: {}".format(err))
    finally:
        if tempfile:
            try:
                os.unlink(tempfile)
            except OSError:
                print("Could not delete the tempfile")

0
投票

您可以在此处使用字典而不是列表数据结构。字典将值映射到用户定义的键而不是整数。因此,您可以简单地将整个文件存储在数据结构中,并使用随机访问来更改所需的用户名,而不是通过遍历列表来查找正确的用户名:

from collections import defaultdict
def main():
        inputDict=defaultdict(string)
        with open("fakefacebook.txt",newline="") as f:
          reader=csv.reader(f)
          for row in reader: #for every row in the file
              line = row.split(',') #splits the CSV row into an array

              #sets the key to be the username, and everything else 
              #to be value, and then adds it to inputDict
              inputDict[line[0]] = line[1:] 

          print("CHANGE PASSWORD?!")
          username=input("Enter the username for the required user:")
          newpassword=input("Enter new password")
          if (inputDict[username]):
              inputDict[username] = newpassword
          else: print("No such username!")


          updatepassword(inputDict)

你必须修改你的updatepassword()才能使用dictionary

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