11. 傳遞函式物件

(1) 將函式的參照複製給一個變數

以下是一個例子:

def diff(data):
    if not (isinstance(data, list) or isinstance(data, tuple)):
        raise TypeError('只接收list或tuple型態')
    
    if len(data)==0:
        raise ValueError('需要有資料')
    
    return max(data) - min(data)

#-----------------------------------
print(diff([10, 3, 20]))

b = diff  #將函式diff的參照複製給b
print(b([10, 3, 20]))  #呼叫同一個函式

第13行,函式diff的參照複製給b,因此diff及b指向同一個函式物件。

執行結果:

17 17 0x21af985ef70 0x21af985ef70

說明

(2) 將函式的參照當作引數傳遞

以下是一個例子:

#依照傳入的計算方式計算數值差異
def diff(data, op):
    return op(data)

#第一種計算差異的函式
def op_1(data):
    return max(data) - min(data)

#第二種計算差異的函式
def op_2(data):
    data.sort(reverse=True)
    n = int(len(data)/2)
    return sum(data[:n])/n - sum(data[n:])/(len(data)-n)

#-----------------------------------
print(diff([10, 3, 20, 13, 22, 4], op_1))
print(diff([10, 3, 20, 13, 22, 4], op_2))

第16行,將op_1函數的位址傳給diff的參數op。 第17行,將op_2函數的位址傳給diff的參數op。

執行結果:

19 12.666666666666664

說明:

問題:

寫一個夏季電費函式summer(degree),計算並回傳電費,各分段收費如下。電費以不同分段之標準收費,如使用電費500度,則前300度每度3.02元,後200度每度5.44元。

 .................................
                     每度(元)   
 .................................
 330度(含)以下         3.02               
 331-700度            5.44        
 701-1000度           6.16         
 1001度(含)以上        6.71         
 .................................

寫一個冬季電費函式winter(degree),計算並回傳電費,各分段收費如下。電費以不同分段之標準收費,如使用電費500度,則前300度每度2.98元,後200度每度4.86元。

 ................................
                    每度(元)   
 ................................
 330度(含)以下         2.98               
 331-700度            4.86        
 701-1000度           5.95         
 1001度(含)以上        6.24         
 ................................

寫一個電費函式elecFee(degree, calculator),傳入用電度數及計費函式(夏季或冬季),計算並回傳電費,小數無條件進位。

測試主程式:

print(f'{elecFee(1200, summer):,.0f}元')
print(f'{elecFee(850, summer):,.0f}元')
print(f'{elecFee(550, summer):,.0f}元')
print(f'{elecFee(425, summer):,.0f}元')
print(f'{elecFee(215, summer):,.0f}元')

print(f'{elecFee(1200, winter):,.0f}元')
print(f'{elecFee(850, winter):,.0f}元')
print(f'{elecFee(550, winter):,.0f}元')
print(f'{elecFee(425, winter):,.0f}元')
print(f'{elecFee(215, winter):,.0f}元')  

測試結果範例:

6,200元 3,934元 2,194元 1,514元 650元 6,106元 3,902元 2,066元 1,459元 641元