我想使用.txt文件来存储应用程序的API令牌,但是如果找到了替换API密钥/令牌的话,我就会陷入困境,如果它在文件中找到的话。这是代码尝试(Python 3.5):
data_to_save = {}
data_to_save['savetime'] = str(datetime.datetime.now())[:19]
data_to_save['api_key'] = key_submitted
data_to_save['user'] = uniqueid
api_exists = False
user_exists = False
with open("databases/api_keys.txt", 'r+') as f:
database = json.loads(f.read())
for i in database:
if i['api_key'] == key_submitted:
send_text_to_user(userid, "[b]Error: That API key is already in use.[/b]", "red")
api_exists = True
if i['user'] == uniqueid:
user_exists = True
if user_exists == True:
if api_exists = True:
send_text_to_user(userid, "[b]Error: Your API key was already saved at another time.[/b]", "red")
else:
f.write(json.dumps(data_to_save)) #Here, StackOverflow
send_text_to_user(userid, "[b]Okay, I replaced your API key.[/b]", "green")
f.close()
if user_exists == False:
writing = open("databases/api_keys.txt", 'a')
writing.write(json.dumps(data_to_save))
writing.close()
我也想知道这是否是最好的方法,或者代码可以优化以及如何。
谢谢,它已经完成了。最终代码:
data_to_save = {'savetime': str(datetime.datetime.now())[:19], 'api_key': key_submitted, 'user': uniqueid}
with open("databases/api_keys.txt", 'r') as f:
database = json.loads(f.read())
for i in database:
if i['user'] == uniqueid:
database.remove(i)
if i['api_key'] == key_submitted:
send_text_to_user(userid, "[b]Error: That API key is already in use.[/b]", "red")
api_exists = True
break
if not api_exists:
database.append(data_to_save)
f.write(json.dumps(database)
send_text_to_user(userid, "[b]Okay, your API key was succesfully stored.[/b]")
使用这种方法,我们甚至不需要在用户存在或不存在的情况下编写不同的保存,因为如果找到它就会删除它,因此当代码运行时它永远不存在而只需要保存每次都有“新”记录,除非API密钥已经属于另一个用户。
答案 0 :(得分:2)
给定代码存在许多问题,所以让我们从头开始:
我们不需要创建空的dict
对象来填充下一行
data_to_save = {}
data_to_save['savetime'] = str(datetime.datetime.now())[:19]
data_to_save['api_key'] = key_submitted
data_to_save['user'] = uniqueid
当我们可以像
那样创建它时data_to_save = {'savetime': str(datetime.datetime.now())[:19],
'api_key': key_submitted,
'user': uniqueid}
if api_exists = True:
所以这一行会导致SyntaxError
(我猜这是一个错字)。
检查
if user_exists == True:
...
are redundant,我们可以写
if user_exists:
...
并具有相同的效果。
在使用with
语句时,我们不需要显式关闭文件,这是context managers:退出with
语句块后的清理。
第一次迭代后的databases/api_key.txt
文件将包含无效的JSON
对象,因为您只是在文件末尾编写新的序列化data_to_save
对象,而您应该修改database
对象(似乎是字典列表)并编写了序列化的新版本,因此我们也不需要r+
模式。
让我们定义实用程序功能,它可以保存新的API密钥数据,如
def save_database(database,
api_keys_file_path="databases/api_keys.txt"):
with open(api_keys_file_path, 'w') as api_keys_file:
api_keys_file.write(json.dumps(database))
然后我们可以有像
这样的东西data_to_save = {'savetime': str(datetime.datetime.now())[:19],
'api_key': key_submitted,
'user': uniqueid}
api_exists = False
user_exists = False
with open("databases/api_keys.txt", 'r') as api_keys_file:
database = json.loads(api_keys_file.read())
# database object should be iterable,
# containing dictionaries as elements,
# so only possible solution -- it is a list of dictionaries
for i in database:
if i['api_key'] == key_submitted:
send_text_to_user(userid, "[b]Error: That API key is already in use.[/b]", "red")
api_exists = True
if i['user'] == uniqueid:
user_exists = True
if user_exists:
if api_exists:
send_text_to_user(userid, "[b]Error: Your API key was already saved at another time.[/b]", "red")
else:
# looking for user record in database
user_record = next(record for record in database
if record['user'] == uniqueid)
# setting new API key
user_record['api_key'] = key_submitted
save_database(database)
send_text_to_user(userid, "[b]Okay, I replaced your API key.[/b]", "green")
if not user_exists:
database.append(data_to_save)
save_database(database)
我已创建目录databases
,其中api_keys.txt
文件包含单行
[]
因为一开始我们没有API密钥。
假设我们错过的对象被定义为
key_submitted = '699aa2c2f9fc41f880d6ec79a9d55f29'
uniqueid = 3
userid = 42
def send_text_to_user(userid, msg, color):
print(msg)
所以使用上面的代码,它给我第一个脚本执行空输出,并在第二个:
[b]Error: That API key is already in use.[/b]
[b]Error: Your API key was already saved at another time.[/b]