带参数的装饰器

时间:2014-08-21 04:57:37

标签: python python-3.x decorator python-decorators

代码如下

 #!/usr/bin/env python3

 def my_dec(func):
    def wrap(w):
        t=func(w)
        return t*4
    return wrap


@my_dec
def testing(n):
    return n


new=testing(3)
print(new)    (this prints 12)

这个例子工作正常,但现在我正在尝试将以下内容添加到装饰器中   @my_dec(100),我需要将给定数字乘以100。

当我尝试这个时

 @my_dec(100)
 def testing(n):
    return n

我得到以下

Traceback (most recent call last):
 File "./deco2", line 10, in <module>
    @my_dec(100)
 File "./deco2", line 5, in wrap
    t=func(w)
TypeError: 'int' object is not callable

如何将100传递给装饰者?

1 个答案:

答案 0 :(得分:5)

在第一个例子中,你正确地将装饰器定义为接受包装函数的函数,并返回一个新函数。

要添加参数,您需要编写一个接受参数的函数,返回装饰器,即返回包含并返回函数的函数。

一种方法:

def my_dec(x):
    def dec(func)
      def wrap(w):
        t=func(w)
        return t*x
      return wrap
    return dec

如果您考虑@语法扩展到的内容,这可能会更加清晰:

@my_dec(100)
def testing(n):
   return n

扩展为:

def testing(n):
   return n
testing = my_dec(100)(testing)

此外,为了降低高嵌套级别,并使装饰器更具可读性和可维护性,您可以定义一个装饰器类,它将其参数置于其__init__中,并在其{{{}中调用包装函数。 1}}。网上有很多例子。您可以先阅读this question

还有一些方法可以让你的装饰器采用可选参数(即使你的两个例子都有效)。


如果您真的想深入了解装饰器,请阅读Graham Dumpleton's blog。强烈推荐。