通过Python的eval()运行JSON?

vybvopom  于 2022-12-15  发布在  Python
关注(0)|答案(4)|浏览(198)

不要这样做

这个问题仍然得到了支持,所以我想给它添加一个警告。如果你使用Python 3,就使用包含的json package。如果你使用Python 2,* 尽你所能转移到Python 3*。如果你被阻止使用Python 3(我的哀悼),使用James Thompson建议的simplejson package
原问题如下。
撇开最佳实践不谈,是否有令人信服的理由这样做?
我正在编写一个用于Google Code项目的post-commit钩子,它通过JSON对象提供提交数据。GC提供了一个HMAC身份验证令牌沿着请求(在JSON数据之外),因此通过验证该令牌,我对JSON数据是良性的(因为不信任Google没有什么意义)和有效的有了很高的信心。
我自己的(简短的)调查表明,JSON恰好是完全有效的Python,除了"\/"转义序列-GC似乎不会生成它。
因此,当我使用Python 2.4(即没有json模块)时,eval()看起来 * 真的 * 很有吸引力。

编辑:声明一下,我非常问这是不是一个好主意。我非常 * 清楚这不是一个好主意,而且我非常怀疑我是否会在未来的任何项目中使用这种技术,即使我最终在这个项目中使用它。我只是想确保我知道如果我这样做会遇到什么样的麻烦。:-)

xghobddn

xghobddn1#

如果您对脚本在一段时间内正常工作感到满意,然后在一些模糊的边缘情况下随机失败,我会使用eval。
如果你的代码健壮性很重要,我会花时间添加simplejson,你不需要C部分来加速,所以把一些.py文件转储到某个目录中应该不难。
举一个可能会让你不舒服的例子,JSON使用Unicode,simplejson返回Unicode,而eval返回str:

>>> simplejson.loads('{"a":1, "b":2}')
{u'a': 1, u'b': 2}
>>> eval('{"a":1, "b":2}')
{'a': 1, 'b': 2}

Edit:eval()行为不同的一个更好的例子:

>>> simplejson.loads('{"X": "\uabcd"}')
{u'X': u'\uabcd'}
>>> eval('{"X": "\uabcd"}')
{'X': '\\uabcd'}
>>> simplejson.loads('{"X": "\uabcd"}') == eval('{"X": "\uabcd"}')
False

编辑2:今天又看到了SilentGhost指出的另一个问题:eval不能正确处理true -〉True,false -〉False,null -〉None。

>>> simplejson.loads('[false, true, null]')
[False, True, None]
>>> eval('[false, true, null]')
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
  File "<string>", line 1, in <module>
NameError: name 'false' is not defined
>>>
lp0sw83n

lp0sw83n2#

最佳实践的要点是,在大多数情况下,忽略它们是一个坏主意。如果我是你,我会使用解析器将JSON解析为Python。尝试一下simplejson,我上次尝试它时,它解析JSON非常简单,而且它声称与Python 2.4兼容。
我不认为不信任Google没有什么意义。我不会不信任Google,但我会验证你从Google获得的数据。我实际上使用JSON解析器的原因就在你的问题中:
我自己的(简短的)调查表明,JSON恰好是完全有效的Python,除了“/”转义序列-GC似乎不会生成它。
是什么让你认为谷歌代码永远不会生成这样的转义序列?
如果你使用正确的工具,解析是一个可以解决的问题。如果你试图走这样的捷径,你最终会被错误的假设所咬,或者你会做一些类似于试图用正则表达式和布尔逻辑来拼凑一个解析器的事情,而你选择的语言已经有了一个解析器。

vvppvyoh

vvppvyoh3#

一个主要区别是JSON中的布尔值是true| false,但Python使用True| False .
不这样做的最重要原因可以概括为:决不能使用eval来解释外部输入,因为这允许执行任意代码。

h5qlskok

h5qlskok4#

eval ing JSON有点像试图通过C++编译器运行XML。
eval是用来计算Python代码的。虽然有一些语法上的相似之处,JSON不是Python代码。见鬼,它不仅不是 Python 代码,而且一开始也不是代码。因此,即使您可以在自己的用例中使用它,我也认为从概念上讲这是一个坏主意。Python是一个苹果,JSON是橘子味的苏打水。

相关问题