八個(gè)重構(gòu)技巧使得Python代碼更Pythonic
1.合并追加到列表聲明
我們從一個(gè)簡(jiǎn)單的開(kāi)始。不是聲明一個(gè)空列表然后附加到它,而是直接用所有元素初始化列表。這縮短了代碼并使意圖更加明確。它的性能也稍微好一些,因?yàn)樗苊饬藢?duì) append() 的函數(shù)調(diào)用。
這同樣適用于填充其他集合類型,如集合和字典。
2 使用items()直接解包字典值
當(dāng)遍歷字典時(shí),你需要鍵和值,那么不要手動(dòng)訪問(wèn)值。而是迭代dictionary.items(),它同時(shí)為你提供鍵和值。
這節(jié)省了我們過(guò)去分配給 players 的行,代碼現(xiàn)在讀起來(lái)更自然,重復(fù)更少。
3. 將 range(len) 替換為枚舉
如果我們需要遍歷列表并且需要同時(shí)跟蹤索引和當(dāng)前項(xiàng),請(qǐng)使用內(nèi)置enumerate()?函數(shù)而不是range(len)。這會(huì)將當(dāng)前索引和當(dāng)前項(xiàng)目作為元組返回。所以我們可以直接在這里查看值,也可以訪問(wèn)帶有索引的項(xiàng)目。
Enumerate? 還帶有一個(gè)可選的start參數(shù)。如果你使用它,計(jì)數(shù)器將從該值開(kāi)始。但請(qǐng)注意,這些項(xiàng)目仍然從第一個(gè)開(kāi)始。
4. 用枚舉調(diào)用替換手動(dòng)循環(huán)計(jì)數(shù)器
這與之前非常相似。有時(shí)我會(huì)看到直接對(duì)項(xiàng)目執(zhí)行迭代的代碼——這本身并不壞——但隨后需要一個(gè)計(jì)數(shù)器,它會(huì)在循環(huán)內(nèi)手動(dòng)遞增。同樣在這里你可以簡(jiǎn)單地使用 enumerate 函數(shù)。這更簡(jiǎn)單,也更快。
4.1 不要手動(dòng)更新計(jì)數(shù)器
如果你只需要計(jì)算項(xiàng)目的數(shù)量,也不要遍歷循環(huán)并手動(dòng)計(jì)算所有項(xiàng)目。相反,只需使用len()函數(shù)來(lái)獲取列表中的元素?cái)?shù)。
5.將條件簡(jiǎn)化為return語(yǔ)句
當(dāng)我們到達(dá)一個(gè)方法的末尾并想要返回 True? 或 False? 時(shí),一種常見(jiàn)的做法是這樣的。如果條件為 True?,我們返回 True?。否則我們最后返回 False。然而,直接返回結(jié)果更簡(jiǎn)潔:
我們?cè)谶@里應(yīng)該注意的一件事是,只有當(dāng)表達(dá)式的計(jì)算結(jié)果為布爾值時(shí)才能這樣做。isinstance()和issubclass()都是返回布爾值的函數(shù),所以這很好。但在下一個(gè)示例中,第一個(gè)表達(dá)式pythonistas是一個(gè)列表而不是布爾值。
如果pythonistas?是一個(gè)有效的非空列表,這將返回列表而不是預(yù)期的布爾值,然后可能是你的應(yīng)用程序中的錯(cuò)誤。因此,為了確保我們?cè)谶@里返回一個(gè)布爾值,我們可以將返回包裝在對(duì) bool()函數(shù)的調(diào)用中。
6.合并條件中的重復(fù)塊
我們應(yīng)該始終尋找機(jī)會(huì)刪除重復(fù)的代碼。這樣做的好地方是if …elif鏈中有多個(gè)相同的塊。
在此示例中,if? 和 elif? 都導(dǎo)致相同的執(zhí)行功能。所以我們可以使用or?組合前兩個(gè)塊來(lái)刪除對(duì)函數(shù)的重復(fù)調(diào)用?,F(xiàn)在,如果我們需要更改process_standard_payment()行,我們可以在一處而不是兩處進(jìn)行。
7.用in運(yùn)算符替換同一個(gè)變量的多次比較
我們甚至可以進(jìn)一步重構(gòu)以前的代碼。由于我們針對(duì)多個(gè)值重復(fù)檢查同一個(gè)變量,我們可以使用 in 運(yùn)算符來(lái)縮短它。如果貨幣值在定義的列表中,我們將執(zhí)行專用操作。
為了再次改進(jìn)這一點(diǎn),我們應(yīng)該在這里使用一個(gè)集合。在集合中查找值更快,而且無(wú)論如何我們都想要這里的唯一元素,所以集合是更好的選擇。
8. 將 for 循環(huán)中的 yield 替換為 yield from
如果你已經(jīng)熟悉生成器,那么這是一個(gè)高級(jí)技巧。一個(gè)經(jīng)常被忽略的小技巧是 Python 的 yield? 關(guān)鍵字對(duì)于可迭代對(duì)象有一個(gè)對(duì)應(yīng)的yield from。
如果你有一個(gè)像列表這樣的可迭代對(duì)象,而不是說(shuō)for item in iterable: yield item?,你可以簡(jiǎn)單地說(shuō)yield from iterable。這更短,并且消除了對(duì)可迭代對(duì)象的手動(dòng)循環(huán),這也可以提高性能。