Python:我应该使用eval,exec还是..?

时间:2011-02-16 16:38:38

标签: python exec eval

我试图让以下声明更加灵活:

for posting in page.findAll(attrs = {"id": re.compile(r'''post\d+''')}):

以下部分从CSV文件动态检索并存储在字符串中(例如名为test的字符串)。 CSV存储在安全的位置,仅供管理员访问。

attrs = {"id": re.compile(r'''post\d+''')}

我可以通过使用eval(test)或exec(test)代替测试来集成变量如下吗?

for posting in page.findAll(test)):

4 个答案:

答案 0 :(得分:5)

如果您想从用户输入运行代码(输入文件内容),您需要evalexec,这些名称或其他名称(具体而言,您需要{{1} for语句 - 赋值是一个语句。)

但你不想(也不应该)这样做,因为那是邪恶的,不安全的,完全没必要的等等。放弃作业(只是存储字典)和exec电话,然后你可以使用re.compile并且你非常安全(你仍然应该捕获语法错误和其他可能出错的显示错误信息的错误信息,但恶意代码应该几乎不可能,而且它几乎不会那么脏)。如果您需要,可以在加载后应用ast.literal_eval

答案 1 :(得分:1)

除非您完全无法控制CSV源,否则请不惜一切代价避免这些类型的加载。

  • 使用pickle模块将正则表达式保存为seriliazed数据(或者更好,只保存字符串)
  • 使用json模块
  • 将数据保存为JSON
  • 使用csv模块
  • 将其写入文件

然后反过来从文件中获取数据。

如果您无法控制CSV生成,请尝试使用splitre模块手动提取数据。

evalexec是“最后机会解决方案”。除非你没有别的办法,否则不要使用它们。

答案 2 :(得分:1)

最安全的是ast.literal_eval()

>>> args = ast.literal_eval('{"a":1}')
>>> args
{'a': 1}

您可以将其用作:

some_function_or_method(**args)

答案 3 :(得分:0)

两者都不是 - 这是Python - 您可以编写一些命名参数和所需的值来将函数称为字典。在这种情况下,键值为“attrs”的字典也是字典。在调用函数时,只需在字典名称前面添加“**”:

test= {"attrs": {\"id\": re.compile(r'''post\d+''')} }

for posting in page.findAll(**test}):
   (...)