使用exec()执行从文本文件读取的代码是一种错误的做法吗?

2024-04-26 00:57:44 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图从一个文本文件中读取数据,其中列出了一个变量名并为其指定了一个值。你知道吗

例如

manufacturer_num = 12345

我想把这些数据存储到已经初始化的类变量中。类变量的名称与文本文件中的变量相同。在这种情况下使用exec()是一种不好的做法吗?有更好的方法吗?你知道吗

下面是我目前拥有的代码。文本文件很长。你知道吗

 def initialize(self):
        f = open(self.path, "r")
        for x in range(self.init_var_len):
            line = f.readline()
            if "=" in line:
                split_string = line.split("=")
                split_string[0] = split_string[0].strip()
                split_string[1] = split_string[1].strip()
                exec("self." + split_string[0] + "=" + "type(self." + split_string[0] + ")(" + "'"+split_string[1]+"'"+")")

        f.close()

        for each in self.__dict__.keys():
            print eval("self." + each)

Tags: 数据inself名称forstringline读取数据
1条回答
网友
1楼 · 发布于 2024-04-26 00:57:44

是的。使用exec是不好的做法。

exec可以执行任意的代码。最重要的问题是您是否总是隐式信任输入文件?答案应该是no,除非您在您个人正在生成的数据上使用此代码一次。你知道吗

下面是一个输入文件的示例,您的代码将读取该文件,然后立即删除整个硬盘驱动器。你知道吗

manufacturer_num = 12345'); import os; os.system('rm -rf /

(由于明显的原因,我实际上并没有对此进行测试。)

即使您在自己生成的数据上使用代码,但在将来,您可能会因为为代码编写的格式错误的输入文件而受到伤害。你知道吗

假设您的数据格式保持不变,并且不深入讨论如何使用类变量,下面是我将如何编写代码。你知道吗

def initialize(self):
    with open(self.path, "r") as f:
        for x, line in enumerate(f):
            line = line.strip()
            if not line:
                continue  # Skip blank lines
            name, value = [s.strip() for s in line.split("=", maxsplit=1)]
            if '=' in value:
                raise ValueError(
                    f'Unexpected multiple "=" in line {x}: {line}')
            # Initialization depends on self.path. Don't let the file
            # overwrite it. Also, limit ourselves to class variables
            # because, hopefully, they're declared explicitly in the
            # code, and the OP said class variables.
            cls = type(self)
            if not hasattr(cls, name) or name == 'path':
                raise AttributeError(name)
            expected_type = type(getattr(cls, name))
            setattr(self, name, expected_type(value))
    # vars is the canonical way of accessing self.__dict__
    for name, value in vars(self).items():
        print(name, value)

相关问题 更多 >