2016-10-29 26 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')而不是例外情况