#python #explain #quine
#python #объясните #куайн
Вопрос:
_='_=%r;print (_%%_) ';print (_%_)
(Редактировать: я получил ваш ввод и исправил код, спасибо за исправление.)
Это самый короткий куайн, который вы можете написать на Python (мне сказали). Куайн — это код, который возвращает сам себя.
Может кто-нибудь объяснить мне эту строку кода, как будто я ничего не знаю о Python? Кстати, я использую Python 3.x.
То, что я ищу, — это посимвольное объяснение того, что происходит.
Спасибо.
Комментарии:
1. Несерьезно: самый короткий куайн должен быть пустым текстовым файлом.
2. Почему это не куайн? Это программа, которая печатает свой собственный исходный код.
3. @DanD.: Запустите его. Сравните выходные данные с исходным кодом. Это не соответствует.
4. Правильный куайн
_='_=%r;print (_%%_) ';print (_%_)
5. @user2357112 Друг, дорогой друг, я ни в коем случае не эксперт. Я знаю, как работают строковые литералы, но я никогда не видел чего-то настолько сжатого (учитывая, что большинство людей хотят удобочитаемости (см. PEP 8)). Я был просто сбит с толку тем, как это работает, и я все еще учусь.
Ответ №1:
Как указано в комментариях, правильный куайн _='_=%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 (_%_)
который является точной копией того, что создало его в первую очередь, то есть куайна.