python进阶小技巧
Python進階小技巧
記錄3個近日學習到的python進階技巧,既不是初級技巧,也不是非常高級的奇技淫巧,所以姑且稱為進階技巧,分別是:with, singledispatch和Flattening。
1. 實現自定義方法的with
1.1 Magic Method
Magic Method直譯成魔術方法,簡單的說就是python中用雙下劃線包裹起來的方法,《流暢的Python》一書中也把這類方法叫做dunder(double underline) method,雙下方法。Python中類的構造函數__init__就是一種最常見的魔術方法。要實現with,就需要2種魔術方法:__enter__和__exit__。
__enter__方法用于管理執行with后返回的實例,并且可以賦值給as關鍵詞之后的變量。
__exit__則顧名思義,定義了with退出時的操作,并對異常進行處理。
下面寫一個非常簡單的demo
from websocket import create_connectionclass Demo:def __init__(self, uri):self.ws = create_connection(uri)def __enter__(self):return self.wsdef __exit__(self):self.ws.close()demo非常簡單,創建一個websocket連接,并且可以使用with方法來調用。如果不使用with,那么每次建立連接之后,都需要手動顯式的去close掉,否則就會有一些僵尸連接長期的掛在那里。用demo中的寫法,那么在with執行完畢后,__exit__方法會自動的來替你關閉這個連接,省心省力。
1.2 contextlib
1.1中的魔術方法,固然是非常的清晰明了,但是我實現上面那么簡單的功能,就要創建一個類,實現3種魔法方法,顯得繁瑣了些。為此,python提供了一個非常簡便的裝飾器——contextlib。使用contextlib重寫一下上面那段代碼:
from contextlib import contextmanager@contextmanager def demo(uri):ws = create_connection(uri)try:yield wsfinally:ws.close()可以把其中的try部分理解成剛才的__enter__方法,finally部分則對應__exit__方法。
兩種寫法各有千秋,完全可以根據喜好和具體場景來選擇合適的實現方法。我還是更喜歡Magic Method實現的方法,__enter__和__exit__看起來更清晰和直白,使用裝飾器的方法相比之下有種過于隱晦的感覺。
2. 單重派發singledispatch
作為一個python程序員,你完全可以在不知道functools存在的情況下寫幾萬行業務代碼而沒有任何障礙,但若能熟練使用functools模塊中的各種功能,你就可以寫出妖艷風騷的多的pythonic代碼。
singledispatch正是functools里的一種方法,single很好理解,就是單個的,dispatch詞匯量達標的同學也都知道,是派遣派出的意思,合在一起就是單重派發了,它所做的事情,就是把不同數據類型的參數,派發到同名,但內容不同的函數模塊去。
比如這一段代碼:
def foo(arg):if isinstance(arg, str):print(f"{arg} is str")elif isinstance(arg, int):print(f"{arg} is int")else:print(f"{arg} is unknown")foo的功能一目了然,就是根據參數arg的不同類型來輸出不同的內容,現在用singledispatch來重寫一下這段代碼:
from functools import singledispatch@singledispatch def foo(arg):print(f"{arg} is unknown")@foo.register def _(arg: int):print(f"{arg} is int")@foo.register def _(arg: str):print(f"{arg} is str")從python3.7開始,可以通過類型注解的方式實現單重派發,之前的版本,需要在register中指定類型。
上面兩種寫法孰優孰劣我也不做評判,我把這個記錄下來僅僅是因為,我終于發現了類型注解的一個實際用處!!從3.5出現以來,我一直以為類型注解只是一種毫無卵用的另類注釋而已!
3. 拉平(Flattening)
問:怎么用最簡單的代碼把[[1], [2, 3], [4, 5, 6]]變成[1, 2, 3, 4, 5, 6]?
我的第一反應是這樣的:
一個字,low,那怎么寫逼格更高呢:
a = [[1], [2, 3], [4, 5, 6]] l = sum(a, [])沒想到吧,sum還有這功能。當然,如果是列表嵌套列表再嵌套列表的復雜格式,要拉平就寫個lamda函數吧。
總結
以上是生活随笔為你收集整理的python进阶小技巧的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c#如何实现叫号操作_C#开发银行叫号系
- 下一篇: websocket python爬虫_p