通过Python运行JSON';s eval()?

通过Python运行JSON';s eval()?,python,json,Python,Json,撇开最佳实践不谈,是否有令人信服的理由不这样做 我正在编写一个post-commit钩子,用于Google代码项目,该项目通过JSON对象提供提交数据。GC在请求中提供HMAC身份验证令牌(在JSON数据之外),因此通过验证该令牌,我获得了JSON数据是良性的(因为不信任Google没有什么意义)和有效的高度信心 我自己的(简短的)调查表明,JSON恰好是完全有效的Python,除了“\/”转义序列,GC似乎不会生成该序列 因此,当我使用Python2.4(即nojsonmodule)时,eva

撇开最佳实践不谈,是否有令人信服的理由不这样做

我正在编写一个post-commit钩子,用于Google代码项目,该项目通过JSON对象提供提交数据。GC在请求中提供HMAC身份验证令牌(在JSON数据之外),因此通过验证该令牌,我获得了JSON数据是良性的(因为不信任Google没有什么意义)和有效的高度信心

我自己的(简短的)调查表明,JSON恰好是完全有效的Python,除了
“\/”
转义序列,GC似乎不会生成该序列

因此,当我使用Python2.4(即no
json
module)时,
eval()
看起来非常诱人


编辑:为了记录在案,我非常不想问这是否是个好主意。我很清楚事实并非如此,而且我非常怀疑我是否会在未来的项目中使用这种技术,即使我最终在这个项目中使用它。我只是想确保我知道如果我这样做会遇到什么样的麻烦。:-)

最佳实践的要点是,在大多数情况下,忽视它们是个坏主意。如果我是你,我会使用解析器将JSON解析为Python。试一试,当我上次尝试它时,解析JSON非常简单,它声称与Python2.4兼容

我不认为不信任谷歌没有什么意义。我不会不信任他们,但我会核实你从他们那里得到的数据。我实际使用JSON解析器的原因就在您的问题中:

我自己(简短)的调查表明,JSON恰好是完全有效的Python,但“/”转义序列除外,GC似乎不会生成该序列

是什么让你认为谷歌代码永远不会生成这样的转义序列


如果使用正确的工具,解析是一个已解决的问题。如果你试图走这样的捷径,你最终会被错误的假设所困扰,或者当你选择的语言已经存在一个解析器时,你会尝试用正则表达式和布尔逻辑将解析器拼凑在一起。

如果你对你的脚本在一段时间内运行良好感到满意,然后在一些模糊边缘的情况下随机失败,我会选择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}
编辑: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
>>> 
>>simplejson.load(“[false,true,null]”)
[假、真、无]
>>>eval(“[false,true,null]”)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“”,第1行,在
NameError:未定义名称“false”
>>> 

<代码> > p> <代码> EVA/CONT> ING JSON有点像通过C++编译器运行XML。p>
eval
用于评估Python代码。尽管在语法上有一些相似之处,JSON不是Python代码。见鬼,它不仅不是Python代码,也不是一开始就可以使用的代码。因此,即使您可以在您的用例中使用它,我认为这在概念上是一个坏主意。Python是一个苹果,JSON是橘子味的苏打水。

一个主要区别是JSON中的布尔值是
true
false
,但Python使用
true


不这样做的最重要原因可以概括为:
eval
不应用于解释外部输入,因为这允许任意代码执行。

如果我不是在托管环境中运行,我可能会使用simplejson。不幸的是,我对我的Python环境没有太多的控制权,我怀疑解决如何添加自定义包比编写实际脚本要花更长的时间;最多50行。类似地,我不知道GC不会开始生成那个转义序列,但如果它开始生成,脚本自然会安全地失败,很明显它被破坏了,修复也很容易。如果修复很容易,为什么不先以修复的方式进行呢?因为它涉及使用正则表达式来计算反斜杠。现在,脚本中没有任何正则表达式,如果可以的话,我将保留它。:-)下面是纯python中的simplejson端口,用于与您类似的情况:。我从来没用过,但我觉得这比评估好。这个港口看起来不错。可能值得在它上面运行来自原始simplejson的单元测试,看看它们是否通过了:+1“在一些模糊的边缘情况下失败”。关于Unicode,您也提出了一个很好的观点。我很确定它与我的特定用例无关,但这是我以前从未考虑过的;我可以发誓我试过逃生密码并让它们工作。现在对它们进行测试,它们会失败,正如您在这里所示。我一定是产生幻觉了^另外,如果使用C加速,simplejson可以返回字符串和unicode的混合,这似乎对修复不感兴趣——哇,这实际上很奇怪。对真/假/空文本的简单修复:
eval(“[false,true,null]”,{'false':false,'true':true,'null':None})注意,你应该为全局服务器发送一些东西,以防止访问GualalsStaseStaseL.,只是让我想通过C++编译器运行XML,看看我是否可以编译它。哦,模板。