Search code examples
pythonrepr

Learn Python the hard way, exercise 10.4


#Combine %r with double-quote and single-quote escapes and print them out. 
#Compare %r with %s. Notice how %r prints it the way you'd write it in your file, 
#but %s  prints it the way you'd like to see it?

This is what I wrote for the exercise:

1) mybugs1 = "Guido said: %r and moved on." %'I \'love\' \"my\" bugs'

2) mybugs2 = "Stallman said: %s and moved on." % 'I \'love\' \"my\" bugs'

3) print mybugs1

4) print mybugs2 

Output

Guido said: 'I \'love\' "my" bugs' and moved on.

Stallman said: I 'love' "my" bugs and moved on.

Question

%r doesn't print everything the way I'd write it in my .py file (for example it prints "my" instead of \"my\" at line 1). Why?


Solution

  • there are several ways to write string literals in python, with single or double quotes, single-line or multiline, raw or normal. None of that is preserved in the string itself, though; once the parser parses it, no information remains about how it was presented in the source; it doesn't even need to be in the source, you could generate the string dynamically, say, by reading it from a file, asking the user, or turning a number into a string.

    So when you repr() a string, python guesses which way to format it to look like a literal. The rules it uses are simple, if the string contains single quotes but no double quotes, it uses a single-line, double-quote, non-raw literal; In all other cases, it uses a single-line, single-quote, non-raw literal; Stated another way, python prefers single quotes, but if it's formatting a string that has single quotes, but not double quotes, it can repr() that string without backslash escaping the quotes by using a double quoted string.

    remember, repr() doesn't return what you typed, because it doesn't know what you typed; you might never have typed it all. It returns something that can be parsed back into the same value. The identity* is:

    x == eval(repr(x))
    

    not

    x == repr(eval(x))
    

    * repr() is not magical for this either, not all objects implement __repr__ in a way that preserves this constraint. repr is mostly used for providing useful debugging information, not for generating python code