你可能不知道的 Python 技巧

func()File"script.py",line2,infuncreturn0/0ZeroDivisionError:divisionbyzero>>>importpdb>>>pdb.pm()#Post-mortemdebugger>script.py(2)func()->return0/0(Pdb)

大多數時候,打印語句和錯誤信息就足以進行調試,但是有時候,你需要四處摸索,以瞭解程序內部正在發生的事情。在這些情況下,你可以設置斷點,然後程序執行時將在斷點處停下,你可以檢查程序,例如列出函數參數、表達式求值、列出變量、或如上所示僅作單步執行。

pdb 是功能齊全的 Python shell,理論上你可以執行任何東西,但是你還需要一些調試命令,可在此處【4】找到。

15、在一個類中定義多個構造函數

函數重載是編程語言(不含 Python)中非常常見的功能。即使你不能重載正常的函數,你仍然可以使用類方法重載構造函數:

importdatetimeclassDate:def__init__(self,year,month,day):self.year=yearself.month=monthself.day=day@classmethoddeftoday(cls):t=datetime.datetime.now()returncls(t.year,t.month,t.day)d=Date.today()print(f"{d.day}/{d.month}/{d.year}")#14/9/2019

你可能傾向於將替代構造函數的所有邏輯放入__init__,並使用*args 、**kwargs 和一堆 if 語句,而不是使用類方法來解決。那可能行得通,但是卻變得難以閱讀和維護。

因此,我建議將很少的邏輯放入__init__,並在單獨的方法/構造函數中執行所有操作。這樣,對於類的維護者和用戶而言,得到的都是乾淨的代碼。

16、使用裝飾器緩存函數調用

你是否曾經編寫過一種函數,它執行昂貴的 I/O 操作或一些相當慢的遞歸,而且該函數可能會受益於對其結果進行緩存(存儲)?如果你有,那麼有簡單的解決方案,即使用 functools 的lru_cache :

fromfunctoolsimportlru_cacheimportrequests@lru_cache(maxsize=32)defget_with_cache(url):try:r=requests.get(url)returnr.textexcept:return"NotFound"forurlin["https://google.com/","https://martinheinz.dev/","https://reddit.com/","https://google.com/","https://dev.to/martinheinz","https://google.com/"]:get_with_cache(url)print(get_with_cache.cache_info())#CacheInfo(hits=2,misses=4,maxsize=32,currsize=4)

在此例中,我們用了可緩存的 GET 請求(最多 32 個緩存結果)。你還可以看到,我們可以使用 cache_info 方法檢查函數的緩存信息。裝飾器還提供了 clear_cache 方法,用於使緩存結果無效。

我還想指出,此函數不應與具有副作用的函數一起使用,或與每次調用都創建可變對象的函數一起使用。

17、在可迭代對象中查找最頻繁出現的元素

在列表中查找最常見的元素是非常常見的任務,你可以使用 for 循環和字典(map),但是這沒必要,因為 collections 模塊中有 Counter 類:

fromcollectionsimportCountercheese=["gouda","brie","feta","creamcheese","feta","cheddar","parmesan","parmesan","cheddar","mozzarella","cheddar","gouda","parmesan","camembert","emmental","camembert","parmesan"]cheese_count=Counter(cheese)print(cheese_count.most_common(3))#Prints:[('parmesan',4),('cheddar',3),('gouda',2)]

實際上,Counter 只是一個字典,將元素與出現次數映射起來,因此你可以將其用作普通字典:

python print(cheese_count["mozzarella"]) ¨K40K cheese_count["mozzarella"] += 1 print(cheese_count["mozzarella"]) ¨K41K

除此之外,你還可以使用 update(more_words) 方法輕鬆添加更多元素。Counter 的另一個很酷的特性是你可以使用數學運算(加法和減法)來組合和減去 Counter 的實例。

小結

在日常 Python 編程中,並非所有這些特性都是必不可少的和有用的,但是其中一些特性可能會時不時派上用場,並且它們也可能簡化任務,而這本來可能很冗長且令人討厭。

我還要指出的是,所有這些特性都是 Python 標準庫的一部分,雖然在我看來,其中一些特性非常像是標準庫中的非標準內容。因此,每當你要在 Python 中實現某些功能時,首先可在標準庫查看,如果找不到,那你可能看得還不夠仔細(如果它確實不存在,那麼肯定在某些三方庫中)。

如果你使用 Python,那麼我認為在這裡分享的大多數技巧幾乎每天都會有用,因此我希望它們會派上用場。另外,如果你對這些 Python 技巧和騷操作有任何想法,或者如果你知道解決上述問題的更好方法,請告訴我!

相關鏈接

[1] 原文地址: https://martinheinz.dev/blog/1

譯文原文:https://mp.weixin.qq.com/s/vaFL75hm1lx3mvURY4V6_A

[2] Levenshtein distance: https://en.wikipedia.org/wiki/Levenshtein_distance

[3] 在這裡: https://docs.python.org/3/howto/ipaddress.html

[4] 此處: https://docs.python.org/3/library/pdb.html%23debugger-commands#debugger-commands


主要分享 Python基礎、Python進階、Python哲學、編程語言、書籍推薦等內容,另外還有官方 PEP 翻譯與優質外文的翻譯,值得關注一同學習。


分享到:


相關文章: