Python之禪-import this的實現

miracle81192發表於2018-08-10

學過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', '\n', '\n', 'B', 'e', 'a', 'u', 't', 'i', 'f', 'u', 'l', ' ', 'i', 's', ' ', 'b', 'e', 't', 't', 'e', 'r', '.....

通過上面的分析我們可以看到這個非常簡單的功能並沒有用定義一個字串然後列印的簡單方式實現。它的實現利用了chr()函式,get()函式,join()函式,還涉及了列表推導式,是一個非常有內容的實現。

相關文章