App下載

Python 中的有幾種反模式?python常見(jiàn)反模式分享!

流蘇書(shū)包 2021-08-25 15:23:00 瀏覽數(shù) (2169)
反饋

1. 不with用于打開(kāi)文件

當(dāng)您打開(kāi)一個(gè)沒(méi)有該with語(yǔ)句的文件時(shí),您需要記住close()在完成處理后通過(guò)顯式調(diào)用關(guān)閉文件。即使明確關(guān)閉資源,在實(shí)際釋放資源之前也有可能發(fā)生異常。這可能會(huì)導(dǎo)致不一致,或?qū)е挛募p壞。打開(kāi)文件通過(guò)with實(shí)現(xiàn)上下文管理器協(xié)議,當(dāng)執(zhí)行在with塊之外時(shí)釋放資源。

不好的做法:

Python:

new_file = open('some-file.txt', 'r')

# do something exciting

new_file.close()

良好做法:

Python:

with open('some-file.txt', 'r') as fd:

 data = fd.read()

 # do something exciting

2.使用list/ dict/set理解不必要

內(nèi)置類(lèi)似功能all,any,enumerate,iter,itertools.cycle和itertools.accumulate可以直接與發(fā)電機(jī)表達(dá)工作。他們不需要理解。

除了他們,all()并any()在Python也支持短路,但如果使用理解這種行為將丟失。這會(huì)影響性能。

不好的做法:

Python:

...
comma_seperated_names = ','.join([name for name in my_fav_superheroes])

良好做法:

Python:

...
comma_seperated_numbers = ','.join(name for name in my_fav_superheroes)

3. 不必要地使用發(fā)電機(jī)

沒(méi)有必要在對(duì) 的調(diào)用中使用生成器表達(dá)式list,dict或者set因?yàn)閷?duì)于這些類(lèi)型中的每一種都有理解。代替使用list/ dict/set周?chē)善鞅磉_(dá)式,它們可以被寫(xiě)為它們各自的理解。

不好的做法:

Python:

squares = dict((i,i**2) for i in range(1,10))

良好做法:

Python:

squares = {i: i**2 for i in range(1,10)}

4. 在函數(shù)調(diào)用中返回多個(gè)對(duì)象類(lèi)型

在函數(shù)中具有不一致的返回類(lèi)型會(huì)使代碼混亂且難以理解,并可能導(dǎo)致難以解決的錯(cuò)誤。如果函數(shù)應(yīng)該返回給定類(lèi)型(例如整數(shù)常量、列表、元組),但也可以返回其他類(lèi)型,則該函數(shù)的調(diào)用者將始終需要檢查返回值的類(lèi)型。建議從函數(shù)中只返回一種類(lèi)型的對(duì)象。

如果在某些失敗的情況下需要返回空的東西,建議引發(fā)一個(gè)可以干凈地捕獲的異常。

不好的做法:

Python:

def get_person_age(name):
    person = db.get_person(name)
    if person:
        return person.age  # returns an int

    # returns None if person not found

良好做法:

Python:

def get_person_age(name):
    person = db.get_person(name)
    if not person:
        raise Exception(f'No person found with name {name}')
    return person.age  # guaranteed to return int every time

5. 不使用get()從字典中返回默認(rèn)值

這種反模式會(huì)影響代碼的可讀性。我們經(jīng)??吹酱a創(chuàng)建一個(gè)變量,為其分配一個(gè)默認(rèn)值,然后在字典中查找某個(gè)鍵。如果鍵存在,則鍵的值被分配給變量的值。這樣做雖然沒(méi)有什么問(wèn)題,但由于它查詢(xún)了兩次字典,因此冗長(zhǎng)且效率低下,而使用get()字典的方法可以輕松完成。

不好的做法:

Python:

currency_map = {'usd': 'US Dollar'}

if 'inr' in currency_map:
  indian_currency_name = currency_map['inr']
else:
  indian_currency_name = 'undefined'

良好做法:

Python:

currency_map = {'usd': 'US Dollar'}
indian_currency_name = currency_map.get('inr', 'undefined')

6. 不使用items()迭代字典

items字典上的方法返回一個(gè)帶有鍵值元組的可迭代對(duì)象,可以在for循環(huán)中解包。這種方法是慣用的,因此值得推薦。

不好的做法:

Python:

for code in country_map:
    name = country_map[code]
    # do something with name

良好做法:

Python:

for code, name in country_map.items():
    # do something with name
    pass

7.不使用文字語(yǔ)法來(lái)初始化空l(shuí)ist/ dict/tuple

通過(guò)調(diào)用初始化空字典dict()比使用空字面值要慢,因?yàn)槊Q(chēng)dict必須在全局范圍內(nèi)查找,以防它被重新綁定。其他兩種類(lèi)型也是如此 -list()和tuple().

不好的做法:

Python:

my_evans = list()
# Add something to this empty list

良好做法:

Python:

my_evans = []
# Add something to this empty list

8. 在生產(chǎn)代碼中推送調(diào)試器

我們大多數(shù)人至少做過(guò)一次——在調(diào)試代碼時(shí),可能會(huì)發(fā)生在你發(fā)現(xiàn)錯(cuò)誤后推送代碼但忘記刪除調(diào)試器的情況。這很關(guān)鍵,可能會(huì)影響代碼的行為。強(qiáng)烈建議在簽入之前審核代碼以刪除調(diào)試器的調(diào)用。

使用 Python 分析器,您可以在代碼庫(kù)中的所有這些反模式投入生產(chǎn)之前檢測(cè)它們。


0 人點(diǎn)贊