我想要使用eval()函数将字符串转化为字典,但是转化失败,怎么回事?

我想要使用eval()函数将字符串转化为字典。按照网上的方法,我写了以下代码

            with open(file, 'r+', encoding="utf-8") as f:
                data_ = f.read()
                data = eval(data_)
                print(data_)
                print(type(data))

但是,结果却是这样的:

并不是dict
怎么回事?

附件:源代码

from ui_word import Ui_word
from PySide2.QtWidgets import *
from PySide2.QtCore import *
import sys


class Word(QMainWindow, Ui_word):
    def __init__(self):
        super().__init__()
        self.file = None
        self.words = {}
        self.word = ""
        self.words_count = 0
        self.setupUi(self)
        self.show()
        self.pb_file.clicked.connect(self.select_file)
        self.a = None
        self.b = None
        self.data_ = None
        self.data = None

    def select_file(self):
        file_path = QFileDialog.getOpenFileName(caption="选择文件", filter="(*.txt)")
        if file_path[0]:
            file = file_path[0]
            self.lb_path.setText(file)
            with open(file, 'r+', encoding="utf-8") as f:
                data_ = f.read()
                data = eval(data_)
                print(data_)
                print(type(data))

        else:
            QMessageBox.warning(self, "注意", "请重新选择文件")

    def choose_tm(self):
        self.a, self.b = random.choice(list(data.items()))
        print(a, b)


if __name__ == "__main__":
    app = QApplication()
    window = Word()
    sys.exit(app.exec_())

参考GPT和自己的思路:

eval()函数可以将字符串转化为Python表达式进行计算,并返回结果。在你的代码中,你尝试使用eval()函数将读取的文件内容转为字典类型,但是返回的却是set类型。这说明读取的文件内容中可能包含了集合类型的数据,而不是字典类型。

为了解决这个问题,你需要检查文件的内容是否确实是一个字典类型。可以使用json模块将字符串转化为字典类型。另外,也可以先对字符串进行处理,去掉集合类型的数据,再进行转化。例如:

import json

with open(file, 'r+', encoding="utf-8") as f:
    data_ = f.read()
    # 去掉集合类型的数据
    data_ = data_.replace('{', '').replace('}', '').strip()
    data = json.loads('{' + data_ + '}')

这样,读取的文件内容就被成功地转化为了字典类型。

该回答引用GPTᴼᴾᴱᴺᴬᴵ
您的代码中,使用了eval()函数将从文件中读取的字符串转换为Python对象,但是eval()函数的执行结果却不是期望的字典类型,而是set类型。这是因为,从文件中读取的字符串可能不是一个合法的Python字典格式,例如:

'{1, 2, 3}'

这样的字符串可以被eval()函数解析为一个set类型,但不是一个字典类型。

为了避免这个问题,您可以在使用eval()函数之前,先判断从文件中读取的字符串是否符合字典格式,例如:

import ast

with open(file, 'r+', encoding="utf-8") as f:
    data_str = f.read()
    try:
        data_dict = ast.literal_eval(data_str)
    except ValueError:
        print("文件内容不是合法的字典格式")

这里使用了ast模块的literal_eval()函数,它和eval()函数类似,可以将字符串转换为Python对象,但是只支持一部分Python语法,更加安全。如果读取的字符串不符合Python字典格式,literal_eval()函数会抛出ValueError异常。