作用
简单的说,python修饰器就是可以对函数的参数以及返回结果进行操作。
如果已经懂了函数闭包的朋友相信已经大概知道该怎么做了,还有不懂的朋友可以看我的这篇文章——python闭包简记。
理解修饰器
我用一个求取平均分的简单案例来说明修饰器的具体用法。
# 装饰器
def check(func): # 这里传入要处理的函数名
def realCheck(**kwargs): # 这里会获取传入的所有关键字参数,kwargs={'python': 48, 'c': 89, 'java': 86}
"""
这里可以对传入的参数进行操作
"""
avg = func(**kwargs) # 调用函数方法,相当于执行了avgScoe函数
"""
这里对生成的结果进行操作
"""
return avg # 最后将结果返回
return realCheck # 闭包函数经典特征,以内函数作为返回结果
def avgScore(python,c,java): # 定义一个求平均值的方法
return (python+c+java) / 3
score = check(avgScore) # 手动修饰器
print(score(python=48,c=89,java=86)) # 输出结果,注意在这里传入参数
# print(check(avgScore)(python=48,c=89,java=86)) # 当然也能够一气呵成,两步化作一步。
上面代码已经将使用修饰器功能的雏形给打造出来了。也许有同学会问:平常我见到的修饰器不是用 @修饰器名 写在被修饰函数前面的吗?没错确实是,上面写法是另一种形式,我想那种写法应该是修饰器最原本的写法吧!
平时见到的应该是这种写法。
# 装饰器
def check(func): # 这里传入要处理的函数名
def realCheck(**kwargs): # 这里会获取传入的所有关键字参数,,kwargs={'python': 48, 'c':
print(kwargs)
"""
这里可以对传入的参数进行操作
"""
avg = func(**kwargs) # 调用函数方法,相当于执行了avgScoe函数
"""
这里对生成的结果进行操作
"""
return avg # 最后将结果返回
return realCheck # 闭包函数经典特征,以内函数作为返回结果
@check # 注意没有空格
def avgScore(python,c,java): # 定义一个求平均值的方法
return (python+c+java) / 3
print(avgScore(python=48,c=89,java=86)) # 输出结果
ok,我们现在分析一下这部分代码,在check函数中,它需要传入一个函数作为他的参数,然后以内函数(realCheck)作为返回值,执行内函数。说白了check函数的功能仅仅是用来接收avgScore函数,营造环境供realCheck使用而已。当然,check函数里面除了定义realCheck函数也可以定义其他的变量方法等,因为这个案例比较简单,定义realCheck函数即可。在 realCheck 函数中需要接收传递过来的参数,参数与avgScore函数中的参数相对应,因为本来就是修饰它的。接着就是进行相应的逻辑处理了。
最后的难点就在于如何写明修饰器。如果理解了就觉得简单,没理解就觉得很绕。看看能不能理解这句话:就是向 修饰器函数 传入需要 被 修饰的函数,然后还需要一个括号将参数传递进去。 就能实现修饰器函数的功能了。
修饰器的使用
理解完修饰器的大概流程后我们就看看如何去使用它。回想一下修饰器要用来干啥?修饰器的出现就是为了能够更加完善函数,提升代码质量。
看一下上面的代码,有什么问题?没错,python分数太低了,我们学python这么认真怎么可能这么低分?? 修改一波!
# 装饰器
def check(func): # 这里传入要处理的函数名
def realCheck(**kwargs): # 这里会获取传入的所有关键字参数,,kwargs={'python': 48, 'c':
if kwargs["python"] < 95:
kwargs["python"] = 100
avg = func(**kwargs) # 调用函数方法,相当于执行了avgScoe函数
"""
这里对生成的结果进行操作
"""
return avg # 最后将结果返回
return realCheck # 闭包函数经典特征,以内函数作为返回结果
我们对传入的参数进行一个判断,如果python分数低于95分,那么就让他等于100分。其实这个过程就印证了开头说的,修饰器能够对参数进行处理。
接着再来看看有什么问题?如果能够复制代码执行一遍就知道有什么问题了。没错!
我们没有处理小数。算个分数怎么可能有这么多小数的?所以我们还需要进行处理。
# 装饰器
def check(func): # 这里传入要处理的函数名
def realCheck(**kwargs): # 这里会获取传入的所有关键字参数,,kwargs={'python': 48, 'c':
if kwargs["python"] < 95:
kwargs["python"] = 100
avg = func(**kwargs) # 调用函数方法,相当于执行了avgScoe函数
s = int(avg)+0.5
avg = s if avg > s else int(avg)
return avg # 最后将结果返回
return realCheck # 闭包函数经典特征,以内函数作为返回结果
@check # 注意没有空格
def avgScore(python,c,java): # 定义一个求平均值的方法
return (python+c+java) / 3
print(avgScore(python=48,c=89,java=86)) # 输出结果
我们对结果进行处理,如果这个分数的小数部分大于等于0.5那就让他小数部分为0.5,否则不要小数。举个例子,如果是91.666 那么结果就是91.5 如果是91.333 那么结果就是91。这一步就印证了开头所说的能够对返回结果进行处理。
至此,修饰器的基本使用我已经讲解完了,如果有对某一步有疑惑的同学可以在下方留言,我会一一回复。