【干貨】你應(yīng)該知道的Python代碼性能提升技巧
由于互聯(lián)網(wǎng)上充斥著許多Python資源,反而使得部分人不知道從哪下手或者從哪提高,我總結(jié)整理了使用頻率較高的Python編程技巧,旨在幫助自己及各位更上一個(gè)臺(tái)階
1. 優(yōu)化代碼性能和速度的技巧
使用內(nèi)置函數(shù)和庫:Python 有很多高度優(yōu)化的內(nèi)置函數(shù)和庫,可以節(jié)省大量時(shí)間和資源;
避免使用全局變量:全局變量可以從程序中的任何位置訪問,可能會(huì)降低代碼速度,所以盡可能使用局部變量;
使用列表推導(dǎo)式:這個(gè)在我之前的教程中也常說到,列表推導(dǎo)式比 for 循環(huán)更快,更簡潔,并且用更少的代碼行執(zhí)行相同的操作;
避免使用遞歸:遞歸函數(shù)可能會(huì)減慢代碼速度,因?yàn)闀?huì)占用大量內(nèi)存;
使用 NumPy 和 SciPy:這倆可以大大幫助優(yōu)化用于科學(xué)和數(shù)學(xué)計(jì)算的代碼;
使用Cython來加速代碼的關(guān)鍵部分,可以編譯成C,使得速度更快;
在執(zhí)行計(jì)算時(shí)使用“矢量化操作”和“廣播”;
使用多進(jìn)程、多線程或異步來利用多個(gè) CPU同時(shí)運(yùn)行多個(gè)任務(wù);
2. 使用高級(jí)功能,如裝飾器、生成器和元類
裝飾器:裝飾器是一種修改函數(shù)或類行為的方法。?通常用于在不更改底層代碼的情況下添加功能,例如日志記錄或記憶(老八股了);
生成器:生成器是一種在 Python 中創(chuàng)建迭代器的方法。?允許迭代大型數(shù)據(jù)集而無需將整個(gè)數(shù)據(jù)集加載到內(nèi)存中,對(duì)于讀取大文件或處理大量數(shù)據(jù)等任務(wù)很有幫助
元類:元類是一種創(chuàng)建可用于創(chuàng)建其他類的類的方法??捎糜跒轭惗x自定義行為,例如添加方法或?qū)傩?。還可以用于創(chuàng)建元編程,允許編寫生成其他代碼的代碼;
協(xié)程:協(xié)程是一種在Python中創(chuàng)建并發(fā)和異步代碼的方法。允許同時(shí)執(zhí)行多個(gè)任務(wù),并且它們可用于創(chuàng)建簡單、輕量級(jí)的線程;函數(shù)注解:函數(shù)注解是一種為函數(shù)添加元數(shù)據(jù)的方式,可以用來提供函數(shù)參數(shù)、返回值和類型的更多信息,也可以用來指定函數(shù)參數(shù)和返回值的類型;
上下文管理器:上下文管理器是一種以安全高效的方式處理資源(常用的如文件)的方法。允許定義使用資源的上下文,并自動(dòng)處理資源的打開和關(guān)閉;
枚舉:枚舉是一種定義一組命名值的方法,可以用作整數(shù)和字符串的替換。使用 Enum 類創(chuàng)建;
Namedtuples:Namedtuples是具有命名字段的元組的子類,可以通過名稱而不是索引來訪問字段。使用namedtuple函數(shù)創(chuàng)建
3.調(diào)試和處理錯(cuò)誤的一些技巧
使用內(nèi)置的 Python 調(diào)試器 (pdb):內(nèi)置的 Python 調(diào)試器是一個(gè)強(qiáng)大的工具,允許逐行調(diào)試代碼、檢查變量和設(shè)置斷點(diǎn);
使用 print 語句(也是我很多場景下喜歡用的哈哈哈):將 print 語句添加到代碼,通過提供程序執(zhí)行流程和變量值的打印來幫助確定問題的根源;
使用 linter:linter 是一種檢查代碼是否存在語法錯(cuò)誤和潛在錯(cuò)誤的工具??梢栽谶\(yùn)行代碼之前捕獲錯(cuò)誤;
使用單元測試框架:單元測試允許單獨(dú)測試一小段代碼,從而更容易查明錯(cuò)誤的來源;
使用日志庫:日志庫記錄有關(guān)程序執(zhí)行的信息,例如變量值和執(zhí)行流程。對(duì)于跟蹤不常發(fā)生的錯(cuò)誤或了解程序隨時(shí)間變化的行為很有用;
使用try-except塊:Try-except 塊通過捕獲錯(cuò)誤并提供替代執(zhí)行流程來優(yōu)雅地處理錯(cuò)誤,可以幫助編寫健壯且容錯(cuò)的代碼;
使用assert語句:assert 語句檢查給定條件是否為真,如果為假則引發(fā)異常。用于檢查輸入的完整性并可用作調(diào)試輔助工具;
使用日志模塊:日志模塊記錄不同級(jí)別的消息,可用于記錄調(diào)試、信息、警告、錯(cuò)誤和關(guān)鍵消息;
使用traceback模塊:traceback 模塊提取異常的堆棧跟蹤,對(duì)于了解錯(cuò)誤原因和定位代碼中的故障點(diǎn)很有用;
使用錯(cuò)誤跟蹤系統(tǒng):錯(cuò)誤跟蹤系統(tǒng)記錄、跟蹤和管理錯(cuò)誤,并跟蹤錯(cuò)誤修復(fù)的進(jìn)度;
4. 編寫干凈易讀代碼的技巧
使用有意義的變量和函數(shù)名稱:為變量和函數(shù)使用準(zhǔn)確反映其用途和用途的清晰、描述性名稱(這個(gè)太重要了,上學(xué)期間總喜歡亂寫)
使用空格和縮進(jìn):一致地使用空格和縮進(jìn)來分隔代碼塊并使代碼結(jié)構(gòu)清晰;
使用注釋:使用注釋來解釋代碼的目的和代碼中任何不清晰的部分;
保持單行簡短:將代碼行的長度限制在 80 個(gè)字符左右
使用統(tǒng)一的命名約定:例如變量名使用 snake_case,類名使用 CamelCase。
保持函數(shù)體小且專注于某個(gè)任務(wù):使得更容易重用和更容易理解,著名的就是main函數(shù)寫了成百上千行
使用文檔字符串(docstrings):記錄目的、參數(shù)、返回函數(shù)和類的值;
遵循 PEP-8 風(fēng)格指南:該指南提供了編寫干凈可讀的 Python 代碼指南。涵蓋縮進(jìn)、命名約定和空格等。遵循這些準(zhǔn)則將使代碼更加一致并且更易于他人閱讀;
5. 使用高級(jí)數(shù)據(jù)結(jié)構(gòu),如集合、字典和元組
Python 提供了多種高級(jí)數(shù)據(jù)結(jié)構(gòu),可用于以強(qiáng)大而高效的方式存儲(chǔ)和操作數(shù)據(jù)。這些數(shù)據(jù)結(jié)構(gòu)包括集合、字典和元組。
集合:集合是唯一元素的無序集合。集合通常用于成員測試、從列表中刪除重復(fù)項(xiàng)以及交集和并集等數(shù)學(xué)運(yùn)算。使用大括號(hào) {} 或 set() 構(gòu)造函數(shù)定義。例如 my_set = {1, 2, 3, 4}
字典:字典是鍵值對(duì)的無序集合。字典通常用于查找、計(jì)數(shù)和排序。使用花括號(hào) {} 定義,鍵和值由冒號(hào)分隔。例如 my_dict = {‘geeks’: 1, ‘for’: 2, ‘geeks’: 3}
元組:元組是元素的有序集合。元組類似于列表,但它是不可變的,意味著它們的元素一旦創(chuàng)建就無法修改。使用括號(hào) () 或 tuple() 構(gòu)造函數(shù)定義。例如 my_tuple = (1, 2, 3, 4)
這些數(shù)據(jù)結(jié)構(gòu)可以以多種方式使用來解決不同問題。例如,可以使用集合來快速檢查某個(gè)元素是否已存在于數(shù)據(jù)集中,使用字典來高效地存儲(chǔ)和檢索數(shù)據(jù),使用元組將多個(gè)值組合在一起并將它們用作單個(gè)實(shí)體。
重要的是,每種數(shù)據(jù)結(jié)構(gòu)都有自己的優(yōu)缺點(diǎn),為特定任務(wù)選擇正確的數(shù)據(jù)結(jié)構(gòu)可以大大提高代碼的性能和可讀性,這哥仨在之前發(fā)的文章中都有總結(jié)
6. 使用大數(shù)據(jù)集和內(nèi)存管理的技巧
處理大型數(shù)據(jù)集是一項(xiàng)具有挑戰(zhàn)性的任務(wù),需要適當(dāng)?shù)膬?nèi)存管理以避免內(nèi)存不足,并確保代碼高效運(yùn)行。以下是處理大型數(shù)據(jù)集和管理內(nèi)存的一些技巧:
使用內(nèi)存高效的數(shù)據(jù)結(jié)構(gòu):例如,使用內(nèi)存效率更高的 NumPy,而不是使用 Python 的內(nèi)置列表數(shù)據(jù)結(jié)構(gòu);
使用數(shù)據(jù)采樣:在處理大型數(shù)據(jù)集時(shí),首先處理較小的數(shù)據(jù)子集通常很有用。使用隨機(jī)采樣等技術(shù)來完成,有助于減少加載和處理數(shù)據(jù)所需的內(nèi)存量;
使用延遲加載:延遲加載是一種僅在需要時(shí)將數(shù)據(jù)加載到內(nèi)存中的技術(shù),而不是一次加載整個(gè)數(shù)據(jù)集;
使用迭代器和生成器:迭代器和生成器是一種處理大型數(shù)據(jù)集的方法,無需立即將整個(gè)數(shù)據(jù)集加載到內(nèi)存中,允許一次處理一個(gè)數(shù)據(jù);
使用基于磁盤的存儲(chǔ):當(dāng)處理無法放入內(nèi)存的大型數(shù)據(jù)集時(shí),將數(shù)據(jù)存儲(chǔ)在磁盤上通常很有用, HDF5 和 Parquet 等熱門庫允許將大型數(shù)據(jù)集存儲(chǔ)在磁盤上并以內(nèi)存高效的方式訪問;
監(jiān)控內(nèi)存使用情況:定期監(jiān)控程序的內(nèi)存使用情況可以幫助識(shí)別和修復(fù)內(nèi)存泄漏,并優(yōu)化程序的內(nèi)存使用情況。Python 提供了 memory_profiler 和 psutil 等庫來監(jiān)控內(nèi)存使用情況;
7. 處理字符串、數(shù)字和其他數(shù)據(jù)類型的技術(shù)
字符串格式化:Python 使用 format() 方法和 f-strings 提供高級(jí)字符串格式化技術(shù)。允許將動(dòng)態(tài)值插入字符串并使它們更具可讀性。例如,使用“My name is {}”.format(“John”) 將值“John”插入到字符串中;
正則表達(dá)式:Python 提供了一個(gè)名為 re 的模塊使用正則表達(dá)式。正則表達(dá)式是搜索、匹配和操作字符串的強(qiáng)大工具;
字符串方法:Python 提供了多種可用于操作字符串的字符串方法。包括但不限于 .strip() 從字符串的開頭和結(jié)尾刪除空格, .split() 將字符串拆分為子字符串列表,以及 .replace() 將特定子字符串替換;
數(shù)字格式化:Python 同樣使用 format() 方法和 f-strings 提供高級(jí)數(shù)字格式化技術(shù),類似于對(duì)字符串執(zhí)行的操作,可以控制小數(shù)位數(shù)、千位分隔符的存在以及其他格式設(shè)置選項(xiàng);
類型轉(zhuǎn)換:Python 提供了 int()、float() 和 str() 等函數(shù),可用于將一種數(shù)據(jù)類型轉(zhuǎn)換為另一種數(shù)據(jù)類型。這在處理不同類型的數(shù)據(jù)時(shí)非常有用;
小數(shù)精度:Python 的 decimal 模塊提供了一個(gè) Decimal 類,可以用來進(jìn)行高精度的小數(shù)運(yùn)算。對(duì)于浮點(diǎn)數(shù)精度可能不夠的金融和貨幣計(jì)算很有幫助;
高級(jí)數(shù)學(xué)運(yùn)算:Python 提供了一個(gè)數(shù)學(xué)模塊,該模塊提供高級(jí)數(shù)學(xué)函數(shù),例如三角函數(shù)、對(duì)數(shù)、指數(shù)等。又得提到NumPy, 該庫也提供了這些操作的高效實(shí)現(xiàn),例如矩陣操作等。
以上就是本期內(nèi)容,有任何錯(cuò)誤歡迎指出,期待與大家共成長~
我是啥都生,下次再見!