Reputation: 265
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?
Upvotes: 6
Views: 18118
Reputation: 1456
print '% %s' % '' #wrong
print '%% %s' % '' #correct and print '% '
Think about \\ and \.
Upvotes: 2
Reputation: 104772
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).
Upvotes: 7