2016-05-18 14 views
17

Digitando import this restituisce Tim Peters 'Zen di Python. Ma ho notato che ci sono 4 immobili in modulo:Attributi del modulo Python `this`

this.i 
this.c 
this.d 
this.s 

posso vedere che la dichiarazione

print(''.join(this.d.get(el, el) for el in this.s)) 

utilizza this.d per decodificare this.s per stampare lo Zen.

Ma qualcuno può dirmi quali sono gli attributi this.i e this.c?

Presumo che ci siano intenzionalmente - le risposte a this question sembrano suggerire che ci siano altre barzellette da trarre dal testo dello Zen. Mi chiedo se ci sia un riferimento che mi manca con questi 2 valori.

ho notato che i valori variano tra le versioni di Python:

# In v3.5: 
this.c 
Out[2]: 97 
this.i 
Out[3]: 25 

# In v2.6 
this.c 
Out[8]: '!' 
this.i 
Out[9]: 25 
+0

Vorrei sottolineare che la codifica rot13 in effetti rappresenta un debito tecnico non pagato e che l'output del modulo potrebbe essere ora archiviato in chiaro (ma se non è rotto, non aggiustarlo).Credo che la codifica fosse originariamente per mantenere la sorpresa dell'uovo di Pasqua e nascondere la sua stessa esistenza a Guido van Rossum, che non conosceva il modulo "this" fino a quando l'uscita in cui è stata introdotta divenne pubblica. – holdenweb

+0

@holdenweb: aspetta, non perché l'intero modulo sia un grande scherzo sui valori che insegna (cioè la codifica rot13 che rende il codice brutto, complesso, illeggibile e poco pratico allo stesso tempo, per non dire ovvio e duplicazione del costruito nel codec di rot13)? –

+0

Bene, un giorno racconterò la storia di come lo Zen è stato scritto. Basti dire che la gente lo prende molto più seriamente di quanto si pensasse di fare. – holdenweb

risposta

29

i e c sono semplicemente variabili di loop, utilizzati per creare il dizionario d. Da the module source code:

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

Questo costruisce una ROT-13 mapping; ogni lettera ASCII (codepoint da 65 a 90 per i caratteri maiuscoli, da 97 a 122 per i caratteri minuscoli) viene mappata su un'altra lettera ASCII 13 punti lungo l'alfabeto (che riconduce ad A e in avanti). Così A (punto ASCII 65) è associata a N e viceversa (come pure a mappato n):

>>> c, i = 65, 0 
>>> chr(i + c) 
'A' 
>>> chr((i + 13) % 26 + c) 
'N' 

Si noti che se si voleva ROT-13 del testo da soli, c'è un metodo più semplice; basta codificare o decodificare con la rot13 codec:

>>> this.s 
"Gur Mra bs Clguba, ol Gvz Crgref\n\nOrnhgvshy vf orggre guna htyl.\nRkcyvpvg vf orggre guna vzcyvpvg.\nFvzcyr vf orggre guna pbzcyrk.\nPbzcyrk vf orggre guna pbzcyvpngrq.\nSyng vf orggre guna arfgrq.\nFcnefr vf orggre guna qrafr.\nErnqnovyvgl pbhagf.\nFcrpvny pnfrf nera'g fcrpvny rabhtu gb oernx gur ehyrf.\nNygubhtu cenpgvpnyvgl orngf chevgl.\nReebef fubhyq arire cnff fvyragyl.\nHayrff rkcyvpvgyl fvyraprq.\nVa gur snpr bs nzovthvgl, ershfr gur grzcgngvba gb thrff.\nGurer fubhyq or bar-- naq cersrenoyl bayl bar --boivbhf jnl gb qb vg.\nNygubhtu gung jnl znl abg or boivbhf ng svefg hayrff lbh'er Qhgpu.\nAbj vf orggre guna arire.\nNygubhtu arire vf bsgra orggre guna *evtug* abj.\nVs gur vzcyrzragngvba vf uneq gb rkcynva, vg'f n onq vqrn.\nVs gur vzcyrzragngvba vf rnfl gb rkcynva, vg znl or n tbbq vqrn.\nAnzrfcnprf ner bar ubaxvat terng vqrn -- yrg'f qb zber bs gubfr!" 
>>> import codecs 
>>> codecs.decode(this.s, 'rot13') 
"The Zen of Python, by Tim Peters\n\nBeautiful is better than ugly.\nExplicit is better than implicit.\nSimple is better than complex.\nComplex is better than complicated.\nFlat is better than nested.\nSparse is better than dense.\nReadability counts.\nSpecial cases aren't special enough to break the rules.\nAlthough practicality beats purity.\nErrors should never pass silently.\nUnless explicitly silenced.\nIn the face of ambiguity, refuse the temptation to guess.\nThere should be one-- and preferably only one --obvious way to do it.\nAlthough that way may not be obvious at first unless you're Dutch.\nNow is better than never.\nAlthough never is often better than *right* now.\nIf the implementation is hard to explain, it's a bad idea.\nIf the implementation is easy to explain, it may be a good idea.\nNamespaces are one honking great idea -- let's do more of those!" 

Per quanto riguarda la differenza di Python 2.6 (o Python 2.7 è per questo) rispetto a Python 3.5; lo stesso nome di variabile c viene utilizzato anche nella lista di comprensione nella chiamata str.join():

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

In Python 2, list comprehension non ottengono il loro campo di applicazione (a differenza di espressioni elettrogeni e dict e impostare comprensioni). In Python 3 lo fanno e il valore c nella comprensione delle liste non fa più parte dello spazio dei nomi del modulo. Così l'ultimo valore assegnato a cpresso il campo di applicazione del modulo è 97 in Python 3, e this.s[-1] (quindi un '!') in Python 2. Vedere Why do list comprehensions write to the loop variable, but generators don't?

Non è uno scherzo incorporato in questi 1-lettera i nomi delle variabili. Lì sono le battute nello Zen stesso. Come il fatto che tra il codice sorgente per il modulo this e il testo stesso è possibile trovare violazioni per quasi tutte le regole!

Problemi correlati