Как указано в комментариях, правильный quine - _='_=%r;print (_%%_) ';print (_%_)
, используя это, давайте начнем:
;
выполняет команды в строке, поэтому следующее:
_='_=%r;print (_%%_) ';print (_%_)
эквивалентно:
_='_=%r;print (_%%_) '
print (_%_)
В первой строке _
является допустимым именем переменной, которой присваивается строка '_=%r;print (_%%_) '
Используя форматирование строки Python, мыможет вставлять переменную в строки способом printf:
>>> name = 'GNU'
>>> print('%s is Not Unix'%name)
GNU is Not Unix
>>> print('%r is Not Unix'%name)
'GNU' is Not Unix
%s
использует строку, %r
использует любой объект и преобразует объект в представление с помощью функции repr()
.
Теперь представьте, что вы хотите напечатать также %
;строка типа GNU is Not Unix %
.Если вы попробуете следующее,
>>> print('%s is Not Unix %'%name)
В итоге вы получите ValueError
, поэтому вам придется бежать %
с другим %
:
>>> print('%s is Not Unix %%'%name)
GNU is Not Unix %
Возвращаясь к исходному коду, когда вы используете _%_
, вы фактически заменяете% r в _='_=%r;print (_%%_)
на себя, а %%
приводит к %
, потому что первый обрабатывается как escape-символ и, наконец,вы распечатываете весь результат, так что в итоге вы получите:
_='_=%r;print (_%%_) ';print (_%_)
, который является точной копией того, что произвело его в первую очередь, т. е. Quine.