2021-06-27 关于导入文本的字符串类型字典的取值问题

今天在编写注册功能函数时发现,注册成功的用户可以将数据以字典的形式轻松保存至文档,但却无法在 for 循环遍历之后通过 key 取值:

def register():
    """注册函数"""
    user_id = input("请设置您的账号>>>: ")
    with open('user_data.txt', 'rt', encoding='utf-8') as f:
        data = f.read()
        for j in data:
            if j["id"] == user_id:
                print("此用户已存在,换一个")
                break
错误:               
File "/Users/creambluea/PycharmProjects/ATM/core/111.py", line 8, in register
    if j["id"] == user_id:
TypeError: string indices must be integers

原因是写入文档时用户信息数据虽然是字典格式,但在保存为文档之后,其格式转变为字符串格式,因此需要先转换为字典格式,但是由于各字典之间都是独立的,并不是键值对形式,因此不能直接使用 dict 转换格式。

有以下几种方式可以将字符串格式的字典还原为字典:
1.使用 json 模块

import json
user_info= '{"name" : "john", "gender" : "male", "age": 28}'
user_dict = json.loads(user_info)
user_dict >>> {u'gender': u'male', u'age': 28, u'name': u'john'}

但是 json 转换需要注意一个潜在问题: json 语法规定,数组或对象之中的字符串必须使用双引号,不能使用单引号

2.使用 eval 函数

usr_info = '{"name" : "john", "gender" : "male", "age": 28}'
user_dict = eval(user_info)
user_dict >>> {'gender': 'male', 'age': 28, 'name': 'john'}
user_info = "{'name' : 'john', 'gender' : 'male', 'age': 28}"
user_dict = eval(user_info)
user_dict >>> {'gender': 'male', 'age': 28, 'name': 'John'}

通过 eval 进行转换就不存在上面使用 json 进行转换的问题。但是eval虽然方便,但是要注意安全性,可以将字符串转成表达式并执行,就可以利用执行系统命令,删除文件等操作。

3.使用 ast 模块中的 literal_eval

import ast
user = '{"name" : "john", "gender" : "male", "age": 28}'
user_dict = ast.literal_eval(user)
user_dict >>> {'gender': 'male', 'age': 28, 'name': 'john'}
user_info = "{'name' : 'john', 'gender' : 'male', 'age': 28}"
user_dict = ast.literal_eval(user)
user_dict >>> {'gender': 'male', 'age': 28, 'name': 'John'}

使用 ast.literal_eval 进行转换既不存在使用 json 进行转换的问题,也不存在使用 eval 进行转换的 安全性问题。

但是单纯使用以上三种方法均只能转换单个字符串,若是文档中有多个字符串则会报错

Traceback (most recent call last):
  File "/Users/creambluea/PycharmProjects/ATM/core/111.py", line 12, in <module>
    register()
  File "/Users/creambluea/PycharmProjects/ATM/core/111.py", line 5, in register
    data = eval(f.read())
  File "<string>", line 1
    {'id': '1', 'password': '1'}{'id': '1', 'password': '1'}

SyntaxError: invalid syntax

因此,以 ast 模块为例,可以做如下处理

def register():
    """注册函数"""
    user_id = input("请设置您的账号>>>: ")
    with open('user_data.txt', 'rt', encoding='utf-8') as f:
        data = [ast.literal_eval(i) for i in f]
        for j in data:
            if j["id"] == user_id:
                print("此用户已存在,换一个")
                break

通过列表生成式逐个转化即可避免语法错误

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值