重写ConfigParser的get()方法加上eval有什么缺点吗?

1 投票
2 回答
697 浏览
提问于 2025-04-16 07:03

我正在创建一个ConfigParser的子类,这样在我的项目中使用起来会更方便:

class MyConfiguration(ConfigParser.ConfigParser):

    def __init__(self, filename):
        ConfigParser.ConfigParser.__init__(self)
        self.readfp(open(filename))

    def get(self, section, option):
        return eval(ConfigParser.ConfigParser.get(self, section, option))

问题是:如果我在get()方法中加入eval,有没有什么坏处(比如安全问题或者其他意想不到的后果)?

我更希望把eval直接放进MyConfiguration类里,因为我想在配置文件中使用Python的数据类型(比如元组等),但又不想在项目代码中到处使用eval。

2 个回答

1

我不太确定在配置文件中执行任意文本是否是个好主意。一般来说,直接使用eval这个函数被认为是不安全的。

你可以看看这些链接:

  1. Python的eval()在不可信字符串上的安全性?
  2. 在Python中使用eval?

如果你想使用Python的数据类型,最好把它存储为一个Python模块,然后导入它。这样可能是更好的解决方案。

你可以把配置文件分开,把包含Python数据类型的部分放在一个Python模块里,其他的部分则保留在可以被configparser解析的配置文件中。

1

如果你对 eval 的兴趣仅仅是想处理一些字面值(就像你所说的那样),那么你可以使用 ast.literal_eval

这个函数可以读取元组、列表等字面值,而且使用起来很安全,因为它只接受特定的内容。

>>> import ast
>>> a = ast.literal_eval('(1, 2, 3)')
>>> a
(1, 2, 3)
>>> b = ast.literal_eval('__import__("evil")')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.6/ast.py", line 68, in literal_eval
    return _convert(node_or_string)
  File "/usr/lib/python2.6/ast.py", line 67, in _convert
    raise ValueError('malformed string')
ValueError: malformed string

像这样的使用场景正是这个函数设计的目的。

撰写回答