【问题标题】:Why is eval('"\x27"') == eval('"\\x27"')?为什么 eval('"\x27"') == eval('"\\x27"')?
【发布时间】:2018-07-03 15:46:10
【问题描述】:

我对 python 的 eval() 很困惑:

我尝试了eval('"\x27"') == eval('"\\x27"'),结果为True。有人可以解释为什么会这样吗?两个表达式都计算为"'"。我明白为什么eval('"\x27"') 会这样做(评估的字符串有一个字符,它是一个转义的十六进制表示撇号),但eval('"\\x27"') 不应该等于"\\x27"

其次,增加混乱,如果我设置以下变量,

s = "\x27"
t = "\\x27"

那么eval('s') 又是"'",但eval('t')"\\x27"。这是为什么呢?

【问题讨论】:

  • 避免使用eval的原因#5:即使是简单的字符串文字也变得难以阅读。
  • eval('"\\\\x27"') equals "\\x27" 你需要双重转义反斜杠
  • 一个变成 eval("'"),另一个变成 eval("\x27")。 Eval 本身会进行一定程度的非转义,因此它们将是相等的。

标签: python python-3.x


【解决方案1】:

根据文档,eval“将参数解析并评估为 python 表达式”。换句话说,它应用的处理与在程序或 IDLE 中编写 x = "foobar \n" 时应用的处理相同。在此示例中,\n 被转换为换行符(注意,它与文字 \n 不同)。

如果您在 IDLE 中输入 x = "\x27",您将得到 x == "'"x27转义,因为反斜杠因此在评估期间更改。如果您转义反斜杠,则x27 在评估期间不会更改。相反,您只需得到一个带有反斜杠的字符串,后跟x27

现在,如果您再次评估该字符串,您只剩下一个反斜杠 - 似乎转义了 x27。因此,它更改为'

另一种看待这个问题的方式:eval("\x27") 评估参数两次,但它只是第一次更改为"'"eval("\\x27") 也会对参数进行两次评估,首先是 \x27,然后是 "'"


这里有一个更简单的例子来演示它是如何工作的:

>>> x = "\"foobar\""
>>> x == "foobar"
False
>>> x == "\"foobar\""
True
>>> x = eval(x) # changes value of x from "foobar" to just foobar. Still string though, thus still ""
>>> x == "foobar"
True
>>> x == "\"foobar\""
False

这样看:y = "2" 的右侧包含两个组件:y 应该是字符串类型的信息,用两个" 表示,以及 该字符串,由字符2 表示。这两个方面的分离是在您编写的代码的评估期间完成的。字符串对象本身在初始化期间永远不会看到"

所以在上面的例子中,在第一行之后,我们有x,类型为str,值为"foobar"。如果您再次评估,则" 这次不会被解释为x 的一部分,而是作为类型 x。所以eval("\"foobar\"") 基本上将字符串 "foobar" 转换为foobar,如果你想使用Python 语言,你必须写成"\"foobar\"""foobar"

【讨论】:

  • 上面代码中的y是什么?还是没关系?
  • 起来,对不起。也应该是x。固定。
  • @titiree 我已经用更多解释更新了答案。
  • 当你说“另一种看待这个的方式”时:eval("\\x27") 将引发错误。你的意思是eval('"\\x27"') 首先解析字符串"\\x27",然后将"\x27" 作为原始字符串,然后对其进行评估?
【解决方案2】:

对于'"\x27"',反斜杠转义在解析过程中被扩展,所以这是字面意思 '"\'"''"\\x27"' 只去掉反斜杠,即它等于r'"\x27"'

字符串文字上的直接eval() 增加了特殊字符扩展的另一个迭代:在第一种情况下,\'valid escape sequence 产生'。第二种情况与上述相同。

当您使用变量名时,在分配值时只执行一轮反转义。 eval('s') 只是扩展为 s 的值,无需进一步转义。如果你想模拟第一种情况,你需要eval(s),即评估s引用的字符串的值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-01
    • 2018-12-15
    • 2020-03-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多