python学习日记11(装饰器)
闭包
函数还可以嵌套定义,即在一个函数内部可以定义另一个函数,有了嵌套函数这种结构,便会产生闭包。
闭包的产生:函数内的函数以及其自由变量形成。即闭包时一个保留定义函数时存在的自由变量的绑定的函数,这样在调用函数时,绑定的自由变量依旧可用。
闭包可以避免全局变量的使用以及提供某种形式数据的隐藏。当函数中的变量和函数较少且其中某个功能常用时,使用闭包来封装。当变量和函数更加复杂时,则使用类来实现。来一个栗子吧!
# 计算移动平均值的函数
def make_averager():
series = []
def averager(new_value):
series.append(new_value)
total = sum(series)
return total/len(series)
return averager
# 在这里边 series = [] 到第七行 return total/len(series)为闭包,变量series为averager()函数中的自由变量!
装饰器
装饰器就是给已有函数增加额外功能的函数,本质上就是一个闭包函数。
如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure)。
功能特点:
- 不修改已有函数的源代码
- 不修改已有函数的调用方式
- 给已有函数增添额外功能
装饰器和闭包的区别
如果闭包函数的参数有且只有一个,并且是函数类型,那么这个闭包函数称之为装饰器。
写代码要遵循开放封闭原则,它规定已经实现的功能代码不允许被修改,但是可以进行扩展。
装饰器的使用
Python给提供了一个装饰函数更加简单的写法,那就是语法糖,语法糖的书写格式是: @装饰器名字,通过语法糖的方式也可以完成对已有函数的装饰。
# 定义装饰器
def decorator(func):
def inner():
# 在内部函数里面对已有函数进行装饰
print('已添加登录认证')
func()
return inner
@decorator # comment = decorator(comment) 装饰器语法糖对该代码进行了封装 左边comment=inner
def comment():
print('发表评论')
# 调用方式不变
comment()
带有参数的装饰器就是使用装饰器装饰函数的时候可以传入指定参数,语法格式: @装饰器(参数,…)。使用带有参数的装饰器,其实是在装饰器外面又包裹了一个函数,使用该函数接收参数,返回是装饰器,因为 @ 符号需要配合装饰器实例使用。
def return_decorator(flag):
# 装饰器只能接收一个参数并且是函数类型
def decorator(func):
def inner(a, b):
if flag == '+':
print('正在努力执行加法计算')
elif flag == '-':
print('正在努力执行减法计算')
func(a, b)
return inner
# 当调用函数的时候可以返回一个装饰器decorato
return decorator
@return_decorator('+')
# decorator = return_decorator('+'), @decorator => add_num = decorator(add_num)
def add_num(a, b):
result = a + b
print(result)
@return_decorator('-')
def sub_num(a, b):
result = a - b
print(result)
add_num(1, 2)
sub_num(1, 2)
装饰器使用场景
- 函数执行时间的统计
- 输出日志信息
- 不变动原有函数,实现输入参数的处理