python代码,装饰器定义函数可以有几层def?有何区别?
发布于 作者:苏南大叔 来源:程序如此灵动~
本文接着对python的装饰器进行思考,本文研究带参数的装饰器的使用方式。普通的装饰器使用的时候,就是个类似@fn的字符串。那么,在本文的讨论中,类似的使用方式是@fn(args)。

大家好,这里是苏南大叔的程序如此灵动博客,这里记录苏南大叔和计算机代码的故事。本文描述如何使用带参数的装饰器。测试环境:win10,python@3.6.8。
单层def可前,没有()
下面这个装饰器非常简单,直接return fn。这个装饰器直接就接收了fn参数,然后返回了一个函数。
两者按理说是不同的函数,可以有不同的逻辑。
def examination(fn):
print("考试前")
return fn
@examination
def exam(lang):
print("考试:" + lang)
双层def可前可后,不需要()
下面这个装饰器双层def,第一层接收了参数fn,因为已经返回了个函数,所以@后面不需要()。这里其实出现了一个闭包。
def examination(fn):
def anything(*args, **kwargs):
print("苏南大叔考试前")
fn(*args, **kwargs)
print("苏南大叔考试后")
return anything
@examination
def exam(lang):
print("考试:" + lang)
三层def可前可后,可传参数(arg)
这个装饰器有三层def,@()返回了一个函数,这个函数接收fn参数,函数内部返回真正的函数逻辑。这里出现了两个闭包。
def examination(arg1):
def examination(fn):
def anything(*args, **kwargs):
print(arg1,"考试前")
fn(*args, **kwargs)
print("考试后")
return anything
return examination
@examination("sunan")
def exam(lang):
print("考试:" + lang)
分析总结
不知道大家有没有注意到对于@符号后面的字符,有的时候是就仅仅是函数名,没有()。有的时候是(),而且有的时候还带着参数,其实也算是有规律可循的。这里有个检验标准:
- 装饰器的
@语句后面加上(fn),就应该是装饰器定义里面return的函数。 - 被
return的函数,负责处理fn的具体逻辑。定义方式 | 代码层级范例 | 使用方式
| 一层def | ddddddddddddddddddddddddddd def dec(fn) return fn | @dec |
| 二层def | dddddddddd def dec(fn) def logic(a,k) fn(a,k) return logic | @dec |
| 三层def | def dec(arg) def dec(fn) def logic(a,k) fn(a,k) return logic | @dec(arg) |
装饰器函数,首先的任务是必须接收fn参数,然后对这个fn函数进行处理。那么,
@符号后面的字符,带不带(),决定于装饰器定义在哪一个层次接收fn。- 接收
fn参数的层次,需要返回一个实际的逻辑处理函数。 - 处理的逻辑中可以简单加工,返回原函数。
- 也可以前后任意逻辑处理,并在其中接受函数,执行
fn函数,然后return一个函数。 - 一层
def的话,就是直接接收fn,处理后返回原处理函数。 - 两层
def的话,就是第一层接收fn参数,返回第二个def函数,第二层处理被修饰函数的真实参数。 - 三层
def的话,在第一层接收的参数是在@()里面传递的。第二层和第一层的作用同上。
相关链接
- https://newsn.net/say/python-decorators.html
- https://newsn.net/say/python-decorators-2.html
- https://newsn.net/say/python-decorators-3.html
- https://newsn.net/say/python-decorators-4.html
综述
更多python程序,请点击苏南大叔的python相关文章。