赞
踩
当调用完函数后,函数内定义的变量就销毁了,但有时需要保存函数内的这个变量,并在这个变量的基础上完成一系列的操作 ,那怎么办呢? 答案就是使用闭包!
闭包可以保存函数内的变量,而不会随着调用完函数而被销毁。
- # 外部函数
- def 外部函数名(外部参数):
- # 内部函数
- def 内部函数名(内部参数):
- ...[使用外部函数的变量]
- return 内部函数名
①有嵌套:在函数嵌套(函数里面再定义函数)的前提下;
②有引用:内部函数使用了外部函数的变量(还包括外部函数的参数);
③有返回:外部函数返回了内部函数名。
- """
- 累加器
- nonlocal:
- 外部函数的变量必须用nonlocal修饰,这样改变量才可以被内置函数修改
- """
- # 1.定义外部函数
- def func_outer(): # 有嵌套
- # 2.定义外部函数变量
- a = 100
- # 3.定义内部函数
- def func_inner(): # 有嵌套
- # 核心细节:外部函数的变量必须用nonlocal修饰,这样改变量才可以被内置函数修改
- nonlocal a
- # 累加器动作 然后输出
- a = a+1 # 有引用,引用外部函数变量
- print(f'a的值为{a}')
- # 4.返回内置函数
- return func_inner # 有返回,返回内部函数名
-
- # 调用func_outer函数
- my_fn = func_outer() # 等价于: my_fn = func_inner
- my_fn() # 101
- my_fn() # 102
- my_fn() # 103
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
装饰器的作用是不改变原有函数的基础上,给原有函数增加额外功能。 装饰器本质上就是一个闭包函数。
①有嵌套:在函数嵌套(函数里面再定义函数)的前提下;
②有引用:内部函数使用了外部函数的变量(还包括外部函数的参数);
③有返回:外部函数返回了内部函数名;
④有额外功能:给需要装饰的原有函数增加额外功能。
- """
- 装饰器细节:
- 1. 装饰器的目的是: 在不改变原有函数的基上, 给原函数增加 额外功能
- 2. 装饰器常用与法主要是: 语法糖形式, 即: @装饰器名
- 3, 使用装饰器的小技巧: 保证装饰器的 内置函数格式 和 原函数(要被装饰的函数) 格式保持一致,都是无参无返回,无参有返回...
- """
- # 场景一:无参无返回
- # 1.定义装饰器
- def print_info(fn_name): # fn_name: 表示要被装饰的函数名
- def fn_inner(): # 内置函数, 格式要和 原函数(被装饰的函数) 保持一致
- print('正在努力计算中...')
- fn_name()
- return fn_inner
-
- # 2.定义原函数,(即: 要被装饰的函数)
- @print_info # 这个是语法糖写法, 等价于: get_sum = print_info(get_sum)
- def get_sum():
- a = 10
- b = 20
- sum = a + b
- print(f'求和结果为{sum}')
-
- # 3.调用函数
- # get_sum = print_info(get_sum) # 原始写法, 看懂即可, 一般不用.
- get_sum()
-
- # 场景二:无参有返回
- # 1.定义装饰器
- def print_info(fn_name): # fn_name: 表示要被装饰的函数名
- def fn_inner(): # 内置函数, 格式要和 原函数(被装饰的函数) 保持一致
- print('正在努力计算中...')
- return fn_name()
- return fn_inner
-
- # 2.定义原函数,(即: 要被装饰的函数)
- @print_info # 这个是语法糖写法, 等价于: get_sum = print_info(get_sum)
- def get_sum():
- a = 10
- b = 20
- sum = a + b
- print(f'求和结果为{sum}')
- return sum
-
- # 3.调用函数
- # get_sum = print_info(get_sum) # 原始写法, 看懂即可, 一般不用.
- get_sum()
-
- # 场景三:有参无返回
- # 1.定义装饰器
- def print_info(fn_name): # fn_name: 表示要被装饰的函数名
- def fn_inner(a,b): # 内置函数, 格式要和 原函数(被装饰的函数) 保持一致
- print('正在努力计算中...')
- fn_name(a,b)
- return fn_inner
-
- # 2.定义原函数,(即: 要被装饰的函数)
- @print_info # 这个是语法糖写法, 等价于: get_sum = print_info(get_sum)
- def get_sum(a,b):
- sum = a + b
- print(f'求和结果为{sum}')
-
- # 3.调用函数
- # get_sum = print_info(get_sum) # 原始写法, 看懂即可, 一般不用.
- get_sum(100,200)
-
- # 场景四:有参有返回
- # 1.定义装饰器
- def print_info(fn_name): # fn_name: 表示要被装饰的函数名
- def fn_inner(): # 内置函数, 格式要和 原函数(被装饰的函数) 保持一致
- print('正在努力计算中...')
- return fn_name()
- return fn_inner
-
- # 2.定义原函数,(即: 要被装饰的函数)
- @print_info # 这个是语法糖写法, 等价于: get_sum = print_info(get_sum)
- def get_sum():
- a = 10
- b = 20
- sum = a + b
- print(f'求和结果为{sum}')
- return sum
-
- # 3.调用函数
- # get_sum = print_info(get_sum) # 原始写法, 看懂即可, 一般不用.
- get_sum()
-
- # 场景四:有参有返回
- # 1.定义装饰器
- def print_info(fn_name): # fn_name: 表示要被装饰的函数名
- def fn_inner(a,b): # 内置函数, 格式要和 原函数(被装饰的函数) 保持一致
- print('正在努力计算中...')
- return fn_name(a,b)
- return fn_inner
-
- # 2.定义原函数,(即: 要被装饰的函数)
- @print_info # 这个是语法糖写法, 等价于: get_sum = print_info(get_sum)
- def get_sum(a,b):
- sum = a + b
- print(f'求和结果为{sum}')
- return sum
-
- # 3.调用函数
- # get_sum = print_info(get_sum) # 原始写法, 看懂即可, 一般不用.
- get_sum(33,66)
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
- """
- 案例:
- 演示不带参数的装饰器.
- 目的:
- 演示1个装饰器 可以用来 装饰 多个函数
- 需求:
- 定义一个既能装饰减法运算, 又能装饰加法运算的装饰器, 即: 带有参数的装饰器
- """
- # 1.定义装饰器
- def logging(flag): # 有嵌套,接收:装饰器的参数 + -
- def decorator(fn_name): # 有嵌套 接收原函数名
- def inner(num1,num2): # 有嵌套 给函数增加额外功能
- if flag =='+':
- print('正在努力计算 加法 中...')
- if flag =='-':
- print('正在努力计算 减法 中...')
- return fn_name(num1,num2)
- return inner
- return decorator
-
-
- # 2.定义函数,加法运算
- @logging('+')
- def get_sum(a,b):
- sum = a+b
- return sum
-
- # 3.定义函数,减法运算
- @logging('-')
- def get_sub(a,b):
- sub = a-b
- return sub
-
- # 4.调用函数
- sum = get_sum(10,7)
- print(f'相加为{sum}')
-
- sub = get_sub(10,7)
- print(f'相减为{sub}')
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。