python装饰器的要求?

问题描述

我一直在努力理解装饰器。我已经将它们理解为您传递其他函数修改某些功能函数。但是,返回以下类型错误。有人能解释一下 (A) 为什么这是无效的?以及 (B) 应如何修改代码以返回 12?

def dec(x):
    return 2*x

@dec
def func(x,y):
    return x*y

>>>
TypeError                                 Traceback (most recent call last)
<ipython-input-89-355f941cfec0> in <module>
      3 
      4 @dec
----> 5 def func(x,y):
      6     return x*y
      7 

<ipython-input-89-355f941cfec0> in dec(x)
      1 def dec(x):
----> 2     return 2*x
      3 
      4 @dec
      5 def func(x,y):

TypeError: unsupported operand type(s) for *: 'int' and 'function'

解决方法

你的装饰器有一个函数作为参数,需要返回一个函数,而不是一个值。例如:

def dec(fn):
  def newfn(x,y):
    return 2 * fn(x,y)
  return newfn

关键是我要返回一个函数,如果调用该函数将在内部调用 fn,将该结果乘以 2 并返回。

装饰器将一个函数替换为另一个函数。所以这个:

@dec
def mult(x,y):
  return x * y

与此完全相同:

def mult(x,y):
  return x * y
mult = dec(mult)

在这两种情况下,我都将 mult 替换为函数 dec(mult) 返回的任何内容。装饰器语法只是为了方便表达。如果 dec 没有返回一个函数,那么当我尝试调用 mult 时我会得到一个错误。

>>> def dec(fn):
...   return 12
...
>>> @dec
... def mult(x,y):
...   return x * y
...
>>> mult
12
>>> mult(9,5)
Traceback (most recent call last):
  File "<stdin>",line 1,in <module>
TypeError: 'int' object is not callable
>>>

mult 是 12,所以最后一行是 "12(9,5)" 并且 12 不是一个可调用的函数,因此 TypeError。