The Zen of Python, by Tim Peters

the Zen of Python,有点哲思的意味,看了好些遍,大师,import this的意思是要把self放在一边吗?我悟道了。您是说我们应该不用self而用this,要替别人着想的意思吗?

>>> import this

The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
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])

Zen of Python(Python之禅)的源代码解读

当您使用import this调出这个彩蛋时,你应该可以想到,这段代码的源代码大概也就是this.py了,上面是Python之禅的源代码this.py,这段代码完全不符合Python之禅

这段代码非常的隐晦,也很难懂,不过一旦你把这段代码读懂了,你的Python基本语法也算是有些小小入门了。。

代码一开始,先定义了一个"""..."""包裹起来的多行字符串s,这个应该懂吧,但很显然这段字符串就应该是上面那首诗的一种特殊版本,我们可以对照看一下,The Zen of Python, by Tim Peters 它这里写成了Gur Mra bs Clguba, ol Gvz Crgref

猜都猜的出来,T=G, h=u, e=r, t=g r=e等等,那到底是什么规律呢,接着读代码

接下来,d = {}定义了一个空的字典叫d,然后,对c的可能的值65和97进行2个迭代,在每个迭代里面,又对一个叫做i 变量迭代,i是一个通过range()函数产生一个list,其取值从0~25,估计和26个英文字母有关。

现在我们先进行c=65的大迭代,i从0开始小迭代取值,取到26的过程中,我们用这个赋值表达式d[chr(i+c)] = chr((i+13) % 26 + c)对字典d开始第一轮的赋值了,记住,此时c=65, 当i=0~25的时候,左边的表达式其实就是:d[chr(i+c)],也就是d[chr(0+65)]一直到d(chr(25+65)),也就是d["A"]一直到d["Z"]; 而表达式的右边就是chr((i+13)%26+65),i+13在这个小迭代里面,因为i=0~25,所以迭代起来就是13~38,13~38对26取模运算的结果是多少呢,开始是13~25,然后是0~12,那么(i+13)%26+65的结果就是开始是78~90,然后是65~77,那么 chr(i+13)%26+65最后的结果就是chr78~chr90,然后chr65~chr77,也就是字母"N"~"Z",然后是字母"A"~"M" ,综上,在这个迭代里,我们对d进行了赋值,d["A"]="N" d["B"]="O"....d["Z"]="M"

接下来,把小写在跑一遍,最终得到一个完整的26个字母的对应表。

字典的赋值表达式大家应该熟悉,d[key]=value,所以,最后得到的d是个啥呢,d={"A":"N","B":"O"...."Z":"M","a":"n","b":"o"...."z":"m"},如果用图来表示,就是这么个图:

最后呢,是个打印语句,总体结果一定是将s按照字典d的方法解密出来。。具体的做法还是要看这个代码,里面涉及到两个函数,get(arg,arg)的意思是什么呢,help(get)会报错的,因为这个get是字典的函数,所以我们要用help({}.get)来得到它的help...我也是晕了,乱猜的, join函数似乎也出不来,我试试help(str.join)是可以出来的,大家自己百度一下吧。不过,为了弄得更清楚,我们做个实验,把最后一句print "".join([d.get(c, c) for c in s])改一改

思考一下会出什么结果。为什么把原来代码里的那个c改成x也可以?那个c和前面65/97有关吗?

最后,出一个问题,这段代码似乎是吧一个密文解码为明文。那怎么产生这个密文呢?怎么把明文加密成密文呢?

说实在的,上面这段代码有点讨厌,主要讨厌在那套unicode的代码,一般人搞不清楚,更难以利用,但这段代码归根结底是要弄出d那样的一个字典,对吧。。当然直接按照那个图写出来也是个方法,就是有点不像程序员干的。。有没有初级一点的方法呢。。

先介绍一对python内建常数,2.7里叫做string.lowercase/string.uppercase, 3.6里面改成了string.ascii_lowercasestring.ascii_uppercase

有了这段常数,我们再看怎么弄

#以下代码试图产生那种d
import string
letters = list(string.ascii_lowercase)
Letters = list(string.ascii_uppercase)
d = {}
for letter in letters:
    d[letter] = letters[(13+letters.index(letter))%26]
for Letter in Letters:
    d[Letter] = Letters[(13+Letters.index(Letter))%26]
#26个字母的列表如下:
[
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
]


#最后的rot13的密码字典d产生出来是:
{
'a': 'n', 'b': 'o', 'c': 'p', 'd': 'q', 'e': 'r', 'f': 's', 'g': 't', 'h': 'u', 'i': 'v', 'j': 'w', 'k': 'x', 'l': 'y', 'm': 'z',
'n': 'a', 'o': 'b', 'p': 'c', 'q': 'd', 'r': 'e', 's': 'f', 't': 'g', 'u': 'h', 'v': 'i', 'w': 'j', 'x': 'k', 'y': 'l', 'z': 'm',
'A': 'N', 'B': 'O', 'C': 'P', 'D': 'Q', 'E': 'R', 'F': 'S', 'G': 'T', 'H': 'U', 'I': 'V', 'J': 'W', 'K': 'X', 'L': 'Y', 'M': 'Z', 
'N': 'A', 'O': 'B', 'P': 'C', 'Q': 'D', 'R': 'E', 'S': 'F', 'T': 'G', 'U': 'H', 'V': 'I', 'W': 'J', 'X': 'K', 'Y': 'L', 'Z': 'M'
}

更加简单的解决方法

如同你所了解的,我们不过试图来实现一个轮子,一个rot_13加密的函数,来把26个字母颠倒后打印出来对应的字符串。。其实轮子已经有了,就看你知不知道。

以下就是那个现成的轮子,请随意丢给它任何文本,它都能把里面的因为字母予以rot_13颠倒

>>> import codecs
>>> codecs.encode('Life is short, you need Python','rot_13')
'Yvsr vf fubeg, lbh arrq Clguba'