2016-10-29 28 views
1

這段代碼的工作原理是什麼?它來自梯度中的「數據科學劃痕」第8章。爲什麼我需要在另一個函數中包裝一個函數?有一種更可讀的方式來實現這種執行處理?這是對它的解釋。python中的函數裝飾器安全

某些步長可能會導致我們的函數無效輸入。所以,我們需要創建一個返回無窮大(這絕不應該是最低的任何東西)爲無效輸入「安全應用」功能:

def safe(f): 
    """return a new function that's the same as f, 
    except that it outputs infinity whenever f produces an error""" 
    def safe_f(*args, **kwargs): 
     try: 
      return f(*args, **kwargs) 
     except: 
      return float('inf') 
    return safe_f 
+1

請更清楚這部分的代碼是不明確給你。它是無限價值的回報嗎? 「try」和「except」是什麼?是否是'f()'的參數?這是爲什麼這個函數在你的大代碼中工作嗎? –

+0

我對try和except以及解包參數有所瞭解。我理解函數背後的目的而不是實現。我想一個示例函數調用會幫助我理解正在發生的事情,但書中沒有。 – Char

+1

您在下面的答案中有2個很好的用法示例,但請記住'安全'裝飾器並不總是您想要做的,有時例外情況會更多地提供一個'inf'值 –

回答

3

假設我們有一個簡單的功能如下:

def myfunc(n): 
    return 42/n 

,我們這樣做:

print(myfunc(0)) 

我們得到這樣的:

Traceback (most recent call last): 
    File "gash.py", line 14, in <module> 
    print(myfunc(0)) 
    File "gash.py", line 12, in myfunc 
    return 42/n 
ZeroDivisionError: division by zero 

現在我們這樣做:

myfunc = safe(myfunc) 
print(myfunc(0)) 

我們得到這樣的:

inf 

我們稱之爲safe()第二次返回新功能與嵌入式異常處理。我們替換名稱「myfunc」指的是,現在它引用返回的函數。原來的myfunc沒有丟失,在新的裏面叫做f

一個@safe裝飾基本上是在做同樣的事情,myfunc = safe(myfunc)

3

你缺少的函數調用:

比方說,我定義的平均函數是這樣的:如果lst是空

def naive_average(lst): 
    return float(sum(lst))/len(lst) 

會發生什麼?或者如果它包含不是數字的東西? BOOM,例外!

隨着你提到的裝飾,功能應該是這樣的

@safe 
def naive_average(lst): 
    return float(sum(lst))/len(lst) 

現在,稱這是一個空的lst將返回float('inf')而不是例外情況