声明:本内容非盈利性质,也不支持任何组织或个人将其用作盈利用途。本内容来源于参考书或网站,会尽量附上原文链接,并鼓励大家看原文。侵删。
5.2 装饰器
python中的装饰器相当于java中的注解。装饰器用于为函数添加某些修饰性、扩展性的功能,这些功能往往具有通用性。
前面我们已经使用过一些装饰器了,例如:静态方法装饰器@staticmethod、类方法装饰器@classmethod等等。这些都是由python提供的具有通用功能的装饰器。有时,我们可能需要自定义一个装饰器,下面我们就学习关于装饰器的语法。
5.2.1 闭包
装饰器首先是一个闭包,因此我们先要了解什么是闭包。
在嵌套函数的情况下,如果外层函数是有返回值的,并且返回值就是内层函数,这种情况称为闭包。满足如下三个条件就是闭包:
- 是嵌套函数;
- 嵌套函数的外层函数有返回值;
- 内层函数引用了外层函数中的变量。(不符合该项的是不严格的闭包)
定义闭包与使用闭包时要注意以下几点:
- 以内部函数作为返回值时,return后面跟不带括号的内部函数名;
- 如果将外部函数赋给了一个变量,那么可以通过“变量名()”的方式调用内部函数。
下面是一个闭包的例子:
'''
闭包的定义与调用
'''
def func1():a = 100def inner_func1():b = 99print(a,b)return inner_func1 # a=100作为变量可以返回,与a同级的内部函数也可以返回,但注意写函数名不能加括号x = func1() # 将外部函数返回的内部函数赋给了变量x,此时x即表示了内部函数
print(x) # 打印x即打印了内部函数的信息x() # x()的形式即表示调用了内部函数'''
闭包的例子:计数器
'''
def gendrate_count():container = [0]def add_1():container[0] = container[0] + 1print('当前是第{}次访问',format(container[0]))return add_1counter = gennerate_count()counter() # 第1次调用
counter() # 第2次调用
counter() # 第3次调用
# 内部函数add_1即为一个计数器,记录访问次数
闭包有一个重要的特点是:每次调用时,闭包的内部函数是另开内存保存的。如下:
'''
闭包的内部函数都是重新加载的
'''
# 定义一个闭包
def func2(a,b):c = 10def inner_func2():s = a + b + cprint('相加和为:', s)return inner_func2# 将外部函数赋给变量
ifunc2 = func2(6,9)
ifunc2a = func2(2,8)# 使用变量赋给内部函数
ifunc2a() # 输出值为20
ifunc2() # 输出值为25# 虽然两次调用外部函数产生了不同的s值,但通过变量调用内部函数时,两次的s值都保持了各自的数值,即第二次调用外部函数并没有将第一次调用外部函数的值刷新。
闭包之所以可以用函数作为返回值,是因为在python中一且皆对象,函数也是一种对象。