自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Python中 為我們提供了一些獨特的解決方案的方法特性

開發(fā) 前端
在日常的工作中,我們很多需求,無論是常見的、還是不常見的,Python 都為我們提供了一些獨特的解決方案,既不需要自己造輪子,也不需要引入新的依賴。

實際上,在日常的工作中,我們很多需求,無論是常見的、還是不常見的,Python 都為我們提供了一些獨特的解決方案,既不需要自己造輪子,也不需要引入新的依賴(引入新的依賴勢必會增加項目的復雜度)。

但是 Python 有太多功能和特性被我們忽略了,導致我們在遇到問題的時候,沒法第一時間作出良好的決策。

所以,干脆來一起掃清這些被我們忽略的 Python 死角。

裝飾器的妙用

我們經(jīng)常會想完成一些注冊&調(diào)用的功能,比如我們有四個函數(shù):

Python中 為我們提供了一些獨特的解決方案的方法特性

現(xiàn)在我們想將這四個函數(shù)和 +、-、*、/ 四個操作符綁定,那么我們該怎么做?

可能我們第一反應是這樣:

Python中 為我們提供了一些獨特的解決方案的方法特性

但這樣寫起來,有一個很大的問題就是太不美觀了。因為直接對于 dict 的操作從實際上來講可維護性是很差的,那么我們這個地方應該怎么做?

在改進這段代碼之前,我們首先要明確 Python 中一個很重要的概念,即:函數(shù)/方法是:First Class Member 。用不精確的話來講,就是函數(shù)/方法可以作為參數(shù)被傳遞、被使用。

舉個例子:

Python中 為我們提供了一些獨特的解決方案的方法特性

大家可以看到我們將 print_func 這個函數(shù)作為參數(shù)傳遞給 execute 函數(shù)并被調(diào)用。

那么我們來改造下之前的代碼:

Python中 為我們提供了一些獨特的解決方案的方法特性

好了,大家看看,目前整體代碼的可讀性以及可維護性是不是改了很多?

但是我們現(xiàn)在的問題在于,每次都需要在單獨調(diào)用一次 register_operator 函數(shù),這樣也太煩了吧!要不要再改進一下?要得。我們可以用裝飾器來改進一下。

首先,看一個最簡單的裝飾器例子:

Python中 為我們提供了一些獨特的解決方案的方法特性

我們能看到這段函數(shù)的意義是計算函數(shù)的執(zhí)行時間。那么這個原理是什么?

實際上裝飾器是一個語法糖,具體可以參見 PEP318 Decorators for Functions and Methods。

簡而言之,實際上是 Python 替我們做了一個替換過程。以上面的例子為例,這個替換過程就是 add=execute(add) 。

好了,我們就用這個知識點來改進下之前的代碼:

Python中 為我們提供了一些獨特的解決方案的方法特性

這樣我們這段代碼的注冊過程是不是就顯得更優(yōu)雅了?

嗯,是的!實際上 Python 中有很多特性會幫助我們的代碼更簡潔,更優(yōu)美。

接下來這個例子很可能幫我們減輕工作量。

聊聊 OrderedDict

dict 是我們經(jīng)常使用的一種數(shù)據(jù)解構。但是在 Python 3.6 之前 dict 都是無序的,即我插入的順序,和數(shù)據(jù)在 dict 中存放的順序并無關聯(lián)(筆者注:Python 3.6 dict 有序只是新版實現(xiàn)的順帶產(chǎn)物,Python 3.7 正式作為 feature 被固定下來)。

但是很多時候,比如在驗簽等場景,我們需要保證 dict 數(shù)據(jù)存放順序,和我們插入順序是一致的。那么我們該怎么辦?

老板有需求下來了,我們肯定不能告訴老板這個需求沒法做。那我們就自己實現(xiàn)一個 ordereddict 吧。于是,想了想,寫了如下的代碼:

Python中 為我們提供了一些獨特的解決方案的方法特性

通過額外維護一個 list 來維護 key 插入的順序。這段代碼,看似完成了我們的需求,但是實則存在很大問題。大家可以猜猜問題在哪?

3,2,1!

揭曉答案,這段代碼利用 list 來保證 key 的有序性,在刪除的時候, list 的刪除操作,是一個時間復雜度 O(n) 的操作。換句話說,我們的刪除操作隨著內(nèi)部數(shù)據(jù)的增多,所需的刪除時間也變得越長。這對于某些性能敏感的場景是無法接受的。

那要怎么辦呢?事實上,Python 在很早之前就已經(jīng)內(nèi)置了有序字典,即很多人可能都用過的 collections.OrderedDict 。

在 OrderedDict 中, Python 維護了一個雙向鏈表解構,來保證插入的有序性,如下圖所示:

Python中 為我們提供了一些獨特的解決方案的方法特性

在最左側(cè)維護一個衛(wèi)兵節(jié)點,衛(wèi)兵節(jié)點的 next 指針恒指向于數(shù)據(jù)中最后插入的節(jié)點。那么插入新的數(shù)據(jù)時,我們將新的數(shù)據(jù)插入到衛(wèi)兵節(jié)點之后,從而達成維護插入順序的目的。

在刪除的時候,通過額外維護的一個字典找到待刪除的 key 所對應的節(jié)點。這個操作是 O(1) 的復雜度,然后大家都知道,雙向鏈表刪除一個節(jié)點的時間復雜度也是 O(1) 。通過這樣保證我們在即便有大量數(shù)據(jù)的情況下,也能保證相應的性能。

好了,我們按照這個思路來做一個最簡單的實現(xiàn):

Python中 為我們提供了一些獨特的解決方案的方法特性

這只是一個 OrderedDict 的簡化版,如果想完成一個完整的 OrderedDict 還有很多很多的 corner case 要去處理。不過現(xiàn)在,我們可以使用內(nèi)置的數(shù)據(jù)結構去完成我們需求。怎么樣,是不是有了一種幸福的感覺?

隨意聊聊

通過今天的兩個例子,我們發(fā)現(xiàn) Python 提供了相當多的功能去幫助我們完成日常的工作與學習任務。同時通過去深入地了解 Python 內(nèi)部的一些功能實現(xiàn),以便我們能更好地去學習一些知識。

比如,上文提到的 OrderedDict 的實現(xiàn),會讓我們學到雙頭鏈表的一種非常典型的應用,與此同時,雙頭鏈表也會用于諸如 LRU 這樣非常常用的數(shù)據(jù)解構的實現(xiàn)。所以,多去深入了解 Python 的方方面面,有助于我們整體能力的提升。

 

責任編輯:張燕妮 來源: 今日頭條
相關推薦

2009-06-10 10:32:13

ZendPHPJava

2021-12-28 10:43:09

Hbase索引方案

2015-11-23 10:16:12

2009-06-16 13:29:56

JBoss事務

2023-09-04 16:55:18

2010-09-19 16:24:45

無線Mesh無線接入Strix

2009-08-07 19:24:11

全網(wǎng)解決方案WANA移動網(wǎng)絡華為

2014-11-11 09:53:52

SDN

2014-08-04 14:28:37

海爾U+

2010-05-24 18:22:36

jsp MySQL

2011-07-13 12:17:18

網(wǎng)康QoE

2011-07-22 17:06:54

2018-06-01 09:00:59

混合云思科微軟

2021-12-27 09:09:41

物聯(lián)網(wǎng)網(wǎng)絡運營商

2023-05-25 10:23:11

2012-02-20 13:54:28

Radware應用交付應用安全

2014-05-12 13:37:03

FusionSpher華為

2023-05-29 15:47:36

2012-09-22 15:13:31

2013-08-21 14:11:31

點贊
收藏

51CTO技術棧公眾號