Python:我应该使用eval、exec还是其他?
我正在尝试让下面的语句变得更灵活:
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)来整合这个变量,而不是仅仅使用test吗?
for posting in page.findAll(test)):
4 个回答
1
最安全的方法是 ast.literal_eval():
>>> args = ast.literal_eval('{"a":1}')
>>> args
{'a': 1}
你可以这样使用它:
some_function_or_method(**args)
1
如果你对CSV文件的来源完全没有控制权,那就尽量避免使用这些加载方式。
- 使用
pickle
模块把正则表达式保存为序列化的数据(或者更简单点,直接保存成字符串就行) - 使用
json
模块把数据保存为JSON格式 - 用
csv
模块把数据写入文件
然后,要从文件中获取数据时,就反过来做。
如果你无法控制CSV的生成,试着用split
或者re
模块手动提取数据。
eval
和exec
是“最后的解决方案”。除非没有其他办法,否则尽量不要使用它们。
5
如果你想运行用户输入的代码(比如文件内容),你需要用到 eval
或 exec
这类东西,特别是 exec
用于执行语句(赋值就是一种语句)。
不过,你其实不应该这样做,因为这样做很危险、不安全,而且完全没有必要。你可以省去赋值的部分(只保存字典),然后用 ast.literal_eval
来处理,这样就安全多了(当然,你还是需要处理语法错误和其他可能出错的情况,以便显示一个合理的错误信息,但恶意代码几乎不可能执行,而且这样做也干净多了)。如果你觉得有必要的话,可以在加载后再使用 re.compile
。