Самый короткий куайн Python 3. Я этого не понимаю

#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 (_%_)
  

который является точной копией того, что создало его в первую очередь, то есть куайна.