Что делает исходный код этого модуля?

193

Если вы откроете интерпретатор Python и наберете «import this», как вы знаете, он напечатает:

Дзен Питона, Тим Питерс

Красиво лучше, чем безобразно.
Явное лучше, чем неявное.
Простое лучше, чем сложное.
Сложный лучше, чем сложный.
Квартира лучше, чем вложенная.
Разреженный лучше, чем плотный.
Читаемость имеет значение.
Особые случаи не достаточно особенные, чтобы нарушать правила.
Хотя практичность превосходит чистоту.
Ошибки никогда не должны проходить бесшумно.
Если явно не молчать.
Перед лицом двусмысленности откажитесь от соблазна гадать.
Должен быть один - и желательно только один - очевидный способ сделать это.
Хотя этот путь поначалу может быть неочевидным, если вы не голландец.
Сейчас лучше, чем никогда.
Хотя никогда не бывает лучше, чемпрямо сейчас
Если реализацию сложно объяснить, это плохая идея.
Если реализацию легко объяснить, это может быть хорошей идеей.
Пространства имен - одна из отличных идей - давайте сделаем больше!

В исходном коде Python (Lib / this.py) этот текст генерируется любопытным фрагментом кода:

s = """Gur Mra bs Clguba, ol Gvz Crgref

Ornhgvshy vf orggre guna htyl.
Rkcyvpvg vf orggre guna vzcyvpvg.
Fvzcyr vf orggre guna pbzcyrk.
Pbzcyrk vf orggre guna pbzcyvpngrq.
Syng vf orggre guna arfgrq.
Fcnefr vf orggre guna qrafr.
Ernqnovyvgl pbhagf.
Fcrpvny pnfrf nera'g fcrpvny rabhtu gb oernx gur ehyrf.
Nygubhtu cenpgvpnyvgl orngf chevgl.
Reebef fubhyq arire cnff fvyragyl.
Hayrff rkcyvpvgyl fvyraprq.
Va gur snpr bs nzovthvgl, ershfr gur grzcgngvba gb thrff.
Gurer fubhyq or bar-- naq cersrenoyl bayl bar --boivbhf jnl gb qb vg.
Nygubhtu gung jnl znl abg or boivbhf ng svefg hayrff lbh'er Qhgpu.
Abj vf orggre guna arire.
Nygubhtu arire vf bsgra orggre guna *evtug* abj.
Vs gur vzcyrzragngvba vf uneq gb rkcynva, vg'f n onq vqrn.
Vs gur vzcyrzragngvba vf rnfl gb rkcynva, vg znl or n tbbq vqrn.
Anzrfcnprf ner bar ubaxvat terng vqrn -- yrg'f qb zber bs gubfr!"""

d = {}
for c in (65, 97):
    for i in range(26):
        d[chr(i+c)] = chr((i+13) % 26 + c)

print "".join([d.get(c, c) for c in s])
byterussian
источник

Ответы:

184

Это называется кодировкой rot13 :

d = {}
for c in (65, 97):
    for i in range(26):
        d[chr(i+c)] = chr((i+13) % 26 + c)

Создает таблицу перевода как для заглавных (это то, что для 65), так и для строчных (это то, что для 97) символов.

print "".join([d.get(c, c) for c in s])

Печатает переведенную строку.

Эли Бендерский
источник
27
И это может быть реализовано проще как в 2.x, так и в 3.x как import codecs; print(codecs.decode(s, "rot-13")). Написание алгоритма от руки было просто еще одним запутыванием пасхального яйца.
ncoghlan
12
Или просто 'Gur Mra bs Clguba, ol Gvz Crgref'.decode('rot13').
Алекс Брасетвик
3
Может быть, мы должны добавить, что ROT13 был основным методом «шифрования», который использовался в старые дни использования сети 8 ^)
Зейн
53
@OllieFord: в шутку. Все, что делает модуль, от запутывания исходного кода до реализации rot13 с нуля, даже если он встроен в stdlib, напрямую нарушает Zen of Python. Тим Питерс также втиснул некоторые тонкие шутки в сам дзен (обратите внимание, что штрихи на линии TOOWTDI делают это двумя разными способами?).
Абарнерт
7
@abarnert Я думаю, что название модуля, thisтакже является частью шутки, потому что другие языки (например, Java) используют thisаналогично тому, как использует Python self. Печатание import thisвыглядит так же бессмысленно, как печатать import java.self;.
Люк
25

Если вы хотите сделать замену ROT13 вручную - или в своей голове - вы можете проверить это, потому что 13 * 2 = 26 (количество букв английского алфавита), это по сути обмен:

a <-> n
b <-> o
c <-> p
...
m <-> z

A <-> N
B <-> O
C <-> P
...
M <-> Z 

Vs lbh cenpgvfr ybat rabhtu, lbh'yy riraghnyyl znfgre gur Mra bs EBG-13 Нитбевгуз Нарк Эвк Гувф Xyvatba ybbxvat Гркгф Джвгубхг Пбзчгре урыц

ypercubeᵀᴹ
источник
11

Используется кодировка ROT13 . Это используется, потому что это шутка.

Вы также можете использовать функции Python для декодирования строки.

Только Python 2:

import this
print(this.s.decode('rot13'))

Python 2 и 3:

import codecs
print(codecs.decode(this.s, 'rot-13'))
trapwalker
источник
Это было замечено ncoghlan комментария 2 мая '11 помощи import codecs. Я не знаю, нужен ли импорт кодеков или доступность decodeбыла сделана автоматически с какой-то конкретной версией Python. Не могли бы вы дать ссылку на документацию decode, которую вы используете?
Cœur
1
@ Cœur Это также не работает для меня в Python 3.7 в IDLE. Может быть, это был Python 2?
Филип Ш
@ FilipŠ О, вы правы, он работает с Python 2, но не с Python 3. Но в Python 2 вы можете просто сделать это, import thisи он напечатает его напрямую без какого-либо дополнительного кода.
Cœur