日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python进阶小技巧

發布時間:2023/12/20 python 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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]?
我的第一反應是這樣的:

a = [[1], [2, 3], [4, 5, 6]] l = [each for element in a for each in element]

一個字,low,那怎么寫逼格更高呢:

a = [[1], [2, 3], [4, 5, 6]] l = sum(a, [])

沒想到吧,sum還有這功能。當然,如果是列表嵌套列表再嵌套列表的復雜格式,要拉平就寫個lamda函數吧。

總結

以上是生活随笔為你收集整理的python进阶小技巧的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。