Que fait le code source du module «this»?

193

Si vous ouvrez un interpréteur Python et tapez "import this", comme vous le savez, il imprime:

Le Zen de Python, par Tim Peters

Beau est mieux que laid.
L'explicite vaut mieux que l'implicite.
Le simple vaut mieux que le complexe.
Complexe vaut mieux que compliqué.
Plat est mieux que niché.
Clairsemé vaut mieux que dense.
La lisibilité compte.
Les cas spéciaux ne sont pas assez spéciaux pour enfreindre les règles.
Bien que l'aspect pratique l'emporte sur la pureté.
Les erreurs ne devraient jamais passer silencieusement.
À moins d'être explicitement réduit au silence.
Face à l'ambiguïté, refusez la tentation de deviner.
Il devrait y avoir une - et de préférence une seule - façon évidente de le faire.
Bien que cette manière ne soit pas évidente au début, sauf si vous êtes néerlandais.
C'est mieux que jamais.
Bien que jamais ne soit souvent mieux quedès maintenant.
Si l'implémentation est difficile à expliquer, c'est une mauvaise idée.
Si la mise en œuvre est facile à expliquer, cela peut être une bonne idée.
Les espaces de noms sont une excellente idée - faisons-en plus!

Dans le source python (Lib / this.py) ce texte est généré par un curieux morceau de code:

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])
byterussien
la source

Réponses:

184

C'est ce qu'on appelle le codage rot13 :

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

Construit la table de traduction, à la fois pour les caractères majuscules (c'est à cela que sert 65) et minuscules (c'est à cela que sert 97).

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

Imprime la chaîne traduite.

Eli Bendersky
la source
27
Et cela peut en fait être implémenté plus simplement dans les versions 2.x et 3.x comme import codecs; print(codecs.decode(s, "rot-13")). Ecrire l'algorithme à la main comme ça n'était qu'une obscurcissement supplémentaire de l'oeuf de Pâques.
ncoghlan
12
Ou juste 'Gur Mra bs Clguba, ol Gvz Crgref'.decode('rot13').
Alex Brasetvik
3
Peut-être devrions-nous ajouter que ROT13 était la principale méthode de "cryptage" utilisée dans l'ancien usenet jours 8 ^)
Zane
53
@OllieFord: Comme une blague. Tout ce que fait le module, de l'obscurcissement du code source à l'implémentation de rot13 à partir de zéro même s'il est intégré à la stdlib, viole directement le Zen de Python. Tim Peters a également glissé quelques blagues subtiles dans le Zen lui-même (remarquez que les tirets sur la ligne TOOWTDI le font de deux manières différentes?).
abarnert le
7
@abarnert Je pense que le nom du module, thisfait également partie de la blague parce que d'autres langages (par exemple Java) utilisent de la thismême manière que Python self. Taper import thissemble tout aussi inutile que taper import java.self;.
Luc
25

Si vous voulez faire la substitution ROT13 à la main - ou dans votre tête - vous pouvez vérifier que parce que 13 * 2 = 26 (le nombre de lettres de l'alphabet anglais), c'est essentiellement un échange:

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 nytbevguz naq ernq guvf Xyvatba ybbxvat grkgf jvgubhg pbzchgre uryc.

ypercubeᵀᴹ
la source
12

C'est un chiffre de substitution, rot13 .

Michael J. Barber
la source
11

Il utilise le codage ROT13 . Ceci est utilisé parce que c'est une blague.

Vous pouvez également utiliser des fonctions Python pour décoder une chaîne.

Python 2 uniquement:

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

Python 2 et 3:

import codecs
print(codecs.decode(this.s, 'rot-13'))
traqueur
la source
Cela a été remarqué par le commentaire de ncoghlan le 2 mai 2011 en utilisant import codecs. Je ne sais pas si l'importation de codecs est toujours nécessaire ou si la disponibilité de a decodeété rendue automatique avec une version particulière de Python. Pourriez-vous créer un lien vers la documentation du decodeque vous utilisez?
Cœur
1
@ Cœur Cela ne fonctionne pas non plus pour moi dans Python 3.7 dans IDLE. Peut-être que c'était Python 2?
Filip Š
@ FilipŠ oh, vous avez raison, cela fonctionne avec Python 2 mais pas avec Python 3. Mais dans Python 2, vous pouvez simplement le faire import thiset il l'imprimera directement sans aucun code supplémentaire.
Cœur