Why is eval('“/x27”') == eval('“//x27”')?

  • A+

I'm very confused with python's eval():

I tried eval('"/x27"') == eval('"//x27"') and it evaluates to True. Can somebody explain why this is the case? Both expressions evaluate to "'". I understand why eval('"/x27"') does (the string evaluated has a single character, which is an escaped hexadecimal representing an apostrophe), but shouldn't eval('"//x27"') be equal to "//x27"?

Secondly, adding to the confusion, if I set the following variables,

s = "/x27" t = "//x27" 

then eval('s') is again "'", but eval('t') is "//x27". Why is that?


According to the docs, eval "parses and evaluates the argument as a python expression". In other words, it's applying the same processing that is applied if you write x = "foobar /n" inside a program or the IDLE. In this example, /n gets turned into a newline-character (which, note, is not identical to the literal /n).

If you typed x = "/x27" into the IDLE, you'd get x == "'". The x27 is escaped because of the backslash and thus changed during evaluation. If you escape the backslash, then x27 is not changed during evaluation. Instead, you simply get a string with a backslash followed by x27.

Now if you evaluated that string again, you only have one backslash left - seemingly escaping x27. Thus, it is changed to '.

Another way to look at this: eval("/x27") evaluates the argument twice, but it is only changed the first time, to "'". eval("//x27") also evaluates the argument twice, first to /x27, then to "'".

Here's an easier example to demonstrate how this works:

>>> 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 

Look at it like this: The right hand side of y = "2" contains two components: the information that y should be of type string, expressed using the two ", and the value of that string, expressed by the character 2. The separation of these two aspects is done during evaluation of the code you write. The string object itself never sees the " during initialization.

So in the above example, after the first line, we have x of type str with value "foobar". If you evaluate that again, the " are interpreted this time not as part of the value of x but as the type of x. So eval("/"foobar/"") basically transforms the string "foobar" to foobar, which, if you want to use that using the language Python, you have to write as "/"foobar/"" and "foobar".


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: