爱学习,爱生活,会学习,会生活,人生有百学网更精彩!
爱学习 | 爱生活

如何创建带参数的装饰器?

发布于:百学网 2022-09-01

如何创建带参数的装饰器?

  这篇我们继续说装饰器,之前装饰器的例子都是不带参数的例子,但我们经常也见到很多装饰器是有参数的,如果你接触过Flask web框架,你应该对它的路由实现不陌生,它就是用装饰器来实现的,例如:

  @app.route('/foo')def foo(): return 'ok'

  在说装饰器参数前,我们先看一个不带参数的例子,然后逐步分析看如何传递参数,简单的代码如下:

  def comm_decorator(f): def wrapped(*args, **kwargs): print('开始运行函数') response = f(*args, **kwargs) print('函数运行完毕') return response print(f) return wrapped

  @comm_decoratordef fun1(a, b): print('fun1 函数') return a + b

  fun1()

  输出:开始运行函数fun1 函数函数运行完毕

  以上的例子,我们在用装饰器的时候没传参数进去,但实际上装饰器会把他装饰的函数传递进去,而且是整个作为一个参数进行传递,所以如果你认为简单的在装饰器调用的时候加个参数进去,是不行的,会直接报错,因为装饰器需要的是一个函数作为参数传进去,所以这么看是没办法直接传递的,咋办?

  我们先看下装饰器调用方式,上面的方式跟下面的方式是一样的:

  comm_decorator(fun1)

  这个大家应该都知道了,那怎么把参数传递进去,如果我们的装饰器返回的是一个装饰器函数,然后再把我们的要装饰的函数传递进入,就实现了我们参数的传递,像这样的方式调用,看大家是否理解。

  comm_decorator(arg)(fun1)

  如果理解了上面的调用方式,接下来就是代码实现了,比如我们要是实现一个可传数字的装饰器,传递的数字表示函数执行几次,代码如下:

  def exec_many(n): def inner_decorator(fun): def wrapped(*args, **kwargs): for i in range(n): fun(*args, **kwargs) return wrapped return inner_decorator

  @exec_many(3)def fun1(): print('in fun1') fun1()

  输出:in fun1in fun1in fun1

  代码分析,在这里我们定义了一个exec_many的装饰器,它接受一个数字参数,这个参数用来决定执行多少次函数,然后在函数内部定义了一个inner_decorator函数,可以简单理解是个内部装饰器函数,在这个函数下的代码就跟上面不带参数的一样了,最后看看函数返回什么?返回的是inner_decorator,就是把装饰器返回了,所以它返回的是个装饰器,再看它的调用方式,就容易理解的多:

  exec_many(3)(fun1)

  这篇就分享到这里,觉得有用的可以点个"

  作者: Python运维技术 python运维技术

  来源公众号:

  python运维技术

本站(www.100xue.net)部分图文转自网络,刊登本文仅为传播信息之用,绝不代表赞同其观点或担保其真实性。若有来源标注错误或侵犯了您的合法权益,请作者持权属证明与本网联系(底部邮箱),我们将及时更正、删除,谢谢

- END -
  • 相关文章