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



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

我会对建议最简单/最简单的修复(不使用 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,marv@gmail.com,400
smithC,open123,cart@gmail.com,200
blogsJ,2bg123,blog@gmail.com,99

所需输出

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

新文件应包含:

username,password,email,no_of_likes
marvR,**boo123**,marv@gmail.com,400
smithC,open123,cart@gmail.com,200
blogsJ,2bg123,blog@gmail.com,99

关于教学初学者的最佳方法的任何评论/解释也将不胜感激。奇怪的是,Python 没有开发某种模块来使编辑文件中的字段比这个 3 步算法更容易,这对于初学者(我说的是 13-14 岁的人(来说确实非常困难。

到目前为止,其中一个相关问题尚未得到解决。您提到了"教初学者">,因此请考虑将此答案作为其他答案的补充。

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

为此:

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

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

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

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()才能使用字典。

最新更新