Cosa sta facendo il codice sorgente del modulo "this"?


193

Se apri un interprete Python e digiti "import this", come sai, stampa:

Lo Zen di Python, di Tim Peters

Bello è meglio che brutto.
Esplicito è meglio che implicito.
Semplice è meglio di complesso.
Complesso è meglio che complicato.
Flat è meglio di nidificato.
Sparse è meglio che denso.
La leggibilità conta.
I casi speciali non sono abbastanza speciali da infrangere le regole.
Sebbene la praticità superi la purezza.
Gli errori non dovrebbero mai passare silenziosamente.
A meno che non sia esplicitamente messo a tacere.
Di fronte all'ambiguità, rifiuta la tentazione di indovinare.
Dovrebbe esserci uno - e preferibilmente solo un - modo obsoleto di farlo.
Anche se in quel modo all'inizio potrebbe non essere ovvio a meno che tu non sia olandese.
Adesso è meglio che mai.
Anche se spesso non è mai meglio diproprio ora
Se l'implementazione è difficile da spiegare, è una cattiva idea.
Se l'implementazione è facile da spiegare, potrebbe essere una buona idea.
Gli spazi dei nomi sono un'ottima idea per suonare il clacson: facciamo di più!

Nel sorgente Python (Lib / this.py) questo testo è generato da un curioso pezzo di codice:

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])

Risposte:


184

Questo si chiama codifica rot13 :

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

Costruisce la tabella di traduzione, sia per i caratteri maiuscoli (questo è ciò che 65 è per) sia per i caratteri minuscoli (questo è 97 per).

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

Stampa la stringa tradotta.


27
E questo può effettivamente essere implementato più semplicemente sia in 2.xe 3.x come import codecs; print(codecs.decode(s, "rot-13")). Scrivere l'algoritmo a mano in quel modo era solo un'ulteriore offuscamento dell'uovo di Pasqua.
ncoghlan,

12
O semplicemente 'Gur Mra bs Clguba, ol Gvz Crgref'.decode('rot13').
Alex Brasetvik,

3
Forse dovremmo aggiungere che ROT13 era il principale metodo di "crittografia" usato nei vecchi giorni di usenet 8 ^)
Zane

53
@OllieFord: come uno scherzo. Tutto ciò che il modulo fa, dall'offuscare il codice sorgente all'implementazione di rot13 da zero anche se è incorporato nello stdlib, viola direttamente lo Zen di Python. Tim Peters ha anche fatto alcune sottili battute nello stesso Zen (noti i trattini sulla linea TOOWTDI in due modi diversi?).
abarnert,

7
@abarnert Penso che anche il nome del modulo faccia thisparte dello scherzo perché altri linguaggi (ad es. Java) usano thissimili a come usa Python self. Digitare import thissembra inutile quanto scrivere import java.self;.
Luc,

25

Se vuoi effettuare la sostituzione ROT13 a mano - o nella tua testa - puoi verificarlo perché 13 * 2 = 26 (il numero delle lettere dell'alfabeto inglese), è essenzialmente uno scambio:

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.



11

Utilizza la codifica ROT13 . Questo è usato perché è uno scherzo.

Puoi anche usare le funzioni Python per decodificare la stringa.

Solo Python 2:

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

Python 2 e 3:

import codecs
print(codecs.decode(this.s, 'rot-13'))

Ciò è stato notato dal commento di ncoghlan del 2 maggio 11 utilizzando import codecs. Non so se l'importazione di codec sia ancora necessaria o se la disponibilità di sia decodestata resa automatica con una particolare versione di Python. Potresti collegarti alla documentazione di decodeciò che stai utilizzando?
Cœur il

1
@ Cœur Anche questo non funziona per me in Python 3.7 in IDLE. Forse questo era Python 2?
Filip Š

@ FilipŠ oh, hai ragione, funziona con Python 2 ma non con Python 3. Ma in Python 2, puoi semplicemente farlo import thise lo stamperà direttamente senza alcun codice aggiuntivo.
Cor

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.