5
s='s=%r;print(s%%s)';print(s%s)

I understand % is to replace something in a string by s (but actually who to replace?) Maybe more intriguing is, why the print(s%%s) become print(s%s) automatically after %s is replaced by s itself?

bozeng
  • 245
  • 1
  • 2
  • 10

2 Answers2

6

The "%%" you see in that code is a "conversion specifier" for the older printf-style of string formatting.

Most conversion specifiers tell Python how to convert an argument that is passed into the % format operator (for instance, "%d" says to convert the next argument to a decimal integer before inserting it into the string).

"%%" is different, because it directly converts to a single "%" character without consuming an argument. This conversion is needed in the format string specification, since otherwise any "%" would be taken as the first part of some other code and there would be no easy way to produce a string containing a percent sign.

The code you show is a quine (a program that produces its own code as its output). When it runs print(s%s), it does a string formatting operation where both the format string, and the single argument are the same string, s.

The "%r" in the string is a conversion specifier that does a repr of its argument. repr on a string produces the string with quotes around it. This is where the quoted string comes from in the output.

The "%%" produces the % operator that appears between the two s's in the print call. If only one "%" was included in s, you'd get an error about the formatting operation expecting a second argument (since %s is another conversion specifier).

Blckknght
  • 100,903
  • 11
  • 120
  • 169
  • I agree with you. But to note if you use "%%" directly, and print it , it is a double percent. E.g: print("%%") and see the output – bozeng Jan 26 '15 at 07:34
  • It means its behavior is not consistent cross at least print and print with format – bozeng Jan 26 '15 at 07:34
  • Your right, that by itself, `"%%"` is just a string with two percent signs in it. It's only when you use that as a format string that the two characters turn into one. Try `"%%" % ()`, to format the string with no arguments and you'll see it happen. – Blckknght Jan 26 '15 at 07:36
2
print '% %s' % '' #wrong
print '%% %s' % '' #correct and print '% '

Think about \\ and \.

John Hua
  • 1,400
  • 9
  • 15