学过Python的人想必都听过大名鼎鼎的Python之禅:
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!
当你在Python解释器中敲入"import this"的时候它就会出现,那么它是怎么实现的呢?或许你和我的想法一样:定义一个字符串zen_of_python,把上面的字符串传给它,然后print就行了。这确实是非常简单的实现方式,但是当我打开Python的源码文件时惊讶的发现其实它并不是这样实现的。
从Python源码包的Include目录下的this.py我们可以看到它的实现是这样的:
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]))
代码前部的字符串像是一堆乱码,但是从格式上看和Python之禅是一样的。要理解Python之禅是怎样被输出的还是要看下面的代码。
我们首先看两个嵌套的for循环,通过代码不难理解实际上通过这个循环定义了一个字典,这个字典有52个key value。这其实就是将a-z A-Z大小写两套英文字母重新做了对应。具体是怎样对应的就要去看chr()函数了。chr()函数提供了数字和ascii字符对应的功能。在段代码里看似混乱的字符串被重新做了对应,它的对应关系就保存在了d这个字典里。
接下来就是输出的环节了,join后面是一个列表推导式,它会逐个读取每个字符然后找到字典里保存的对应关系。这里用到了get()函数,它的作用是找到字典中key对应的value,第二个参数指定了如果找不到对应的值返回的默认值是什么。之前提到d字典保存了英文大小写总共52个字符的对应值,但是这里面标点符号空格换行符之类的值是没有保存对应关系的,所以在没有找到的情况下会把输入的值原样返回。最后需要join函数吧整个列表拼接成一个字符串,不然打印出来东西就会像是这个样子了:
["T", "h", "e", " ", "Z", "e", "n", " ", "o", "f", " ", "P", "y", "t", "h", "o", "n", ",", " ", "b", "y", " ", "T", "i", "m", " ", "P", "e", "t", "e", "r", "s", " ", " ", "B", "e", "a", "u", "t", "i", "f", "u", "l", " ", "i", "s", " ", "b", "e", "t", "t", "e", "r", ".....
通过上面的分析我们可以看到这个非常简单的功能并没有用定义一个字符串然后打印的简单方式实现。它的实现利用了chr()函数,get()函数,join()函数,还涉及了列表推导式,是一个非常有内容的实现。