讀書筆記(2): 編寫高質(zhì)量python代碼的59個有效方法

前言

《編寫高質(zhì)量python代碼的59個有效方法》這本書分類逐條地介紹了編寫python代碼的有效思路和方法,對理解python和提高編程效率有一定的幫助。本筆記簡要整理其中的重要方法。

承接上文http://www.itdecent.cn/p/15a6050220e6

上一篇筆記主要介紹了關(guān)于基本的python編程思想;
本篇介紹關(guān)于函數(shù)和 類與繼承的編程方法

2. 函數(shù)

函數(shù)作為編程中最基本重要的編程模塊/組織工具,是代碼復(fù)用和重構(gòu)的重要工具

使用異常表示特殊情況,不要返回None

這是一個比較細(xì)微的場景,是能夠體現(xiàn)嚴(yán)謹(jǐn)?shù)木幊趟枷搿?如下所示

def divide(a,b):
    try:
        return a/b
    except ZeroDivisionError:
        return None
  def divide(a,b):
    try:
        return a/b
    except ZeroDivisionError:
        return None
x,y=0,5
result=divide(x,y)
if result is None:
    print('Invalid Inputs')

對異常情況返回None,但當(dāng)分子為0時,會給后續(xù)編程帶來影響(往往不會專門判定None),如下所示,就會出現(xiàn)錯誤,這種錯誤往往比較難發(fā)現(xiàn):

x,y=0,5
result=divide(x,y)
if not result :
    print('Invalid Inputs')

可以通過增加返回值,增添None判定來解決潛在的問題:

def divide(a,b):
    try:
        return True,a/b
    except ZeroDivisionError:
        return False,None

更合適的做法是將異常直接再拋出,調(diào)用函數(shù)時處理異常即可

def divide(a,b):
    try:
        return a/b
    except ZeroDivisionError as e:
        raise ValueError('Invalid inputs') from e
        
x,y=5,0
try:
    res=divide(5,0)
except ValueError:
    print('Invalid inputs')
else:
    print('Result %.1f' % res)

考慮使用生成器改寫直接返回列表的函數(shù)

我們經(jīng)常會利用函數(shù)生成一系列結(jié)果,用列表的形式返回結(jié)果。

## 查找字符串中每個詞的首字母的位置
def index_words(text):
    result=[]
    if text:
        result.append(0)
    for index,letter in enumerate(text):
        if letter==' ':
            result.append(index+1)
    return result
a='This is a test case.'
index_words(a)

這種寫法很常見,這種寫法代碼比較擁擠;而且當(dāng)輸入較長時,列表占用內(nèi)存較大;可以考慮使用生成器

def index_words(text):
    if text:
        yield 0
    for index,letter in enumerate(text):
        if letter==' ':
            yield index+1
list(index_words(a))

通過yield逐次產(chǎn)生結(jié)果,可以通過list()將生成器直接轉(zhuǎn)成list,最常見的寫法是對生成器進(jìn)行迭代。使用生成器的唯一問題是:函數(shù)返回的迭代器是有狀態(tài)的,不能重復(fù)使用。

使用數(shù)量可變的位置參數(shù)

可以使用*args,設(shè)置長度可變的位置參數(shù)


將上例改成下面的形式,減少手工的參數(shù)設(shè)置

def log(message,*values):
    if not values:
        print(message)
    else:
        values_str=', '.join(str(x) for x in values)
        print('%s: %s'%(message,values_str))
log('Numbers',1,2,3)

用關(guān)鍵詞參數(shù)來表達(dá)可選的行為

這種寫法是我們編程常用的,在代碼比較復(fù)雜的情況下,在調(diào)用函數(shù)時指明關(guān)鍵詞參數(shù),能夠幫助調(diào)試,方面函數(shù)迭代。

用只能以關(guān)鍵字形式指定的參數(shù)來確保代碼清晰

關(guān)鍵字形式指定參數(shù)是編程中常用的方法,但有時關(guān)鍵詞較多,可以設(shè)定只能以關(guān)鍵詞形式指定參數(shù)來調(diào)用函數(shù),如下圖所示:

def safe_division(a,b,*,flag1,flag2):
    pass
    return 0
safe_division(1,0,flag1=0,flag2=0)
safe_division(1,0, 0, 0)# 報錯

*號代表后面的參數(shù)均為只能以關(guān)鍵字形式指定的參數(shù),如果以位置參數(shù)指定會報錯。

3. 類與繼承

該部分的方法由于代碼和例子比較長,比較復(fù)雜,僅挑部分知識點出來,想深入了解的可以看原書。

@classmethod

多態(tài)、是得繼承體系重點多個類能夠以各自獨有的方式實現(xiàn)某個方法。具有相同的接口/繼承自相同的抽象類,但有不同的功能。

Python中可以使用@classmethod這種函數(shù)裝飾器來指定成員函數(shù)的多態(tài)。

super初始化父類

傳統(tǒng)初始化父類的方式如下所示,是在子類里用子類實例直接調(diào)用父類的init方法。

這種方式在多重繼承下容易出現(xiàn)問題,可以使用內(nèi)置的super函數(shù)初始化父類:
,class變量是用來準(zhǔn)確地引用當(dāng)前類。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容