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?
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?
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).
print '% %s' % '' #wrong
print '%% %s' % '' #correct and print '% '
Think about \\ and \.