標籤:

優雅的 Python 之 Ellipsis

(P.S.你也可以在我的博客閱讀這篇文章)

Python 是一門非常具有包容性的語氣,體現在一個優秀的工程師可以非常容易優雅高效地完成一件事情,而一個拙略的工程師通過屎一樣的代碼同樣可以做到幾乎一樣的功能。今天,介紹一下 Python 的 Ellipsis~~~

想像這樣一個問題:

如何優雅地生成一個等差數組?比如輸入一個序列的第一、第二項以及最後一項,然後返回這個等差數組。

這裡指的優雅並不是實現代碼上,而是調用方式優雅。那麼,在具體實現之前,我們先看一眼調用的方式吧:

In [1]: gen = SeqGenerator()nnIn [2]: gen[1, 2, ..., 9]n[1, 2, 3, 4, 5, 6, 7, 8, 9]nnIn [3]: gens[20, 16, ..., 0]n[20, 16, 12, 8, 4, 0]n

有意思吧,這樣直觀的方式調用,簡單明了。下面簡單聊聊實現原理吧。

其實,在 object 對象中,有一個 __getitem__ 方法。你可以做如下測試:

In [1]: class Test(object):n ....: def __getitem__(self, item):n ....: print itemnnIn [2]: t = Test()nnIn [2]: t[1]n1nnIn [3]: t[what the fuck]nwhat the fucknnIn [4]: t[:]nslice(None, None, None)nnIn [5]: t[1: 10]nslice(1, 10, None)nnIn [6]: t[1:3:5]nslice(1, 3, 5)nnIn [7]: t[1, 2]n(1, 2)nnIn [8]: t[1, 2, ..., 5]n(1, 2, Ellipsis, 5)n

可以看到,第八行的調用方式與上面產生等差數列的方式基本是一樣的了,但是返回的內容( Test 中事實上並沒有返回,只是直接 print 了)不同,多了一個 Ellipsis。

那麼,對應上面的 SeqGenerator 的實現就一目了然了:

class SeqGenerator(object):n def __getitem__(self, item):n if not (isinstance(item, tuple) and len(item) == 4 and item[2] is Ellipsis):n raise RuntimeError(what the fuck)n return range(item[0], (item[-1]+1, item[-1]-1)[item[0]>item[1]], item[1]-item[0])n

然後就可以愉快地按照上面的示例一樣調用啦。當然,上面的實現比較簡單,沒有完整地考慮到各種情況,如果你願意,可以自行解決之~~~


推薦閱讀:

Python之websocket web模擬tail -F。
如何用爬蟲下載中國土地市場網的土地成交數據?
Python爬蟲簡易代理池

TAG:Python |