Was macht der Quellcode des Moduls "this"?

191

Wenn Sie einen Python-Interpreter öffnen und "import this" eingeben, wird bekanntlich Folgendes ausgegeben:

Das Zen von Python, von Tim Peters

Schön ist besser als hässlich.
Explizit ist besser als implizit.
Einfach ist besser als komplex.
Komplex ist besser als kompliziert.
Wohnung ist besser als verschachtelt.
Spärlich ist besser als dicht.
Lesbarkeit zählt.
Sonderfälle sind nicht speziell genug, um gegen die Regeln zu verstoßen.
Obwohl Praktikabilität die Reinheit übertrifft.
Fehler sollten niemals stillschweigend vergehen.
Sofern nicht ausdrücklich zum Schweigen gebracht.
Verweigern Sie angesichts von Zweideutigkeiten die Versuchung zu raten.
Es sollte einen - und vorzugsweise nur einen - offensichtlichen Weg geben, dies zu tun.
Obwohl dieser Weg zunächst vielleicht nicht offensichtlich ist, es sei denn, Sie sind Niederländer.
Jetzt ist besser als nie.
Obwohl nie oft besser ist alsgerade jetzt.
Wenn die Implementierung schwer zu erklären ist, ist es eine schlechte Idee.
Wenn die Implementierung leicht zu erklären ist, kann dies eine gute Idee sein.
Namespaces sind eine großartige Idee - lasst uns mehr davon machen!

In der Python-Quelle (Lib / this.py) wird dieser Text durch einen merkwürdigen Code generiert:

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
quelle

Antworten:

183

Dies wird als rot13- Codierung bezeichnet:

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

Erstellt die Übersetzungstabelle sowohl für Großbuchstaben (dies ist das, wofür 65 steht) als auch für Kleinbuchstaben (das ist, wofür 97 steht).

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

Druckt die übersetzte Zeichenfolge.

Eli Bendersky
quelle
27
Und das kann tatsächlich einfacher in 2.x und 3.x als implementiert werden import codecs; print(codecs.decode(s, "rot-13")). Das Schreiben des Algorithmus von Hand war nur eine weitere Verschleierung des Ostereies.
Ncoghlan
12
Oder einfach nur 'Gur Mra bs Clguba, ol Gvz Crgref'.decode('rot13').
Alex Brasetvik
3
Vielleicht sollten wir hinzufügen, dass ROT13 die Hauptmethode der "Verschlüsselung" war, die in den alten Usenet-Tagen 8 ^)
Zane
53
@ OllieFord: Als Witz. Alles, was das Modul tut, von der Verschleierung des Quellcodes bis zur Implementierung von rot13 von Grund auf neu, obwohl es in die stdlib integriert ist, verstößt direkt gegen das Zen von Python. Tim Peters hat auch ein paar subtile Witze in den Zen selbst geschlichen (beachten Sie die Striche auf der TOOWTDI-Linie auf zwei verschiedene Arten?).
Abarnert
7
@abarnert Ich denke, der Name des Moduls thisist auch Teil des Witzes, weil andere Sprachen (zB Java) thisähnlich wie Python verwenden self. Tippen import thissieht genauso sinnlos aus wie Tippen import java.self;.
Luc
25

Wenn Sie die ROT13- Substitution von Hand oder in Ihrem Kopf vornehmen möchten, können Sie dies überprüfen, da 13 * 2 = 26 (die Anzahl der Buchstaben des englischen Alphabets) im Wesentlichen ein Austausch ist:

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

ypercubeᵀᴹ
quelle
12

Es ist eine Substitutions-Chiffre, rot13 .

Michael J. Barber
quelle
11

Es verwendet die ROT13- Codierung. Dies wird verwendet, weil es ein Witz ist.

Sie können auch Python-Funktionen verwenden, um Zeichenfolgen zu dekodieren.

Nur Python 2:

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

Python 2 & 3:

import codecs
print(codecs.decode(this.s, 'rot-13'))
Trapwalker
quelle
Dies wurde durch ncoghlan Kommentar am 2. Mai 11 mit bemerkt import codecs. Ich weiß nicht, ob der Import von Codecs noch erforderlich ist oder ob die Verfügbarkeit von decodemit einer bestimmten Version von Python automatisch erfolgt ist. Könnten Sie auf die Dokumentation des von Ihnen verwendeten verlinken decode?
Cœur
1
@ Cœur Dies funktioniert auch nicht für mich in Python 3.7 in IDLE. Vielleicht war das Python 2?
Filip Š
@ FilipŠ oh, du hast recht, es funktioniert mit Python 2, aber nicht mit Python 3. Aber in Python 2 kannst du es einfach tun import thisund es wird direkt ohne zusätzlichen Code gedruckt.
Cœur