内部函数
- 函数里面 定义的 函数 --> 内部函数
- 内部函数 修改 外部的变量 nonlocal
- 内部函数 修改 全局的变量 global
a = 100
def func():
b = 99
def func_son():
global a
nonlocal b
c = 88
b += 1
a += 1
print(a, b, c)
- globals() # 查看全局变量、函数
- locals() # 查看内部变量、函数
闭包
- 是什么?
- 函数中 的概念
- 调用 函数的内部函数、内部变量
- 函数返回自己的内部函数名,这就是闭包
return 内部函数名
def func():
def func_son():
a = 10
print(a)
return func_son # 不加(), 返回的是函数,不是调用函数
x = func() # x 即为 func_son
x() # 给x加() 即 调用 func_son()
闭包的参数、变量
- 闭包的作用域
- 内部函数每次重新加载,但是 内部函数 访问的仍是同一个外部函数
装饰器
- 应用广泛,依赖闭包,是在闭包的基础上的升级
条件一 函数作为参数
条件二 闭包的特点
def decrator(func): # 定义一个装饰器
a = 100
def wrapper(): # 包装 装饰
func() # 调用被装饰函数,保持其原功能
print(' wrapper print a :', a)
return wrapper
decrator(xxx) # 传入函数名 作为参数
如何使用装饰器 @
- 在简单函数上面 @装饰器名字
# 使用装饰器
@decrator
def house():
print('i am 毛坯房')
house()
假如在开发完成后,发现house()函数还有不足,需要丰富一下。
-
更改原函数 – 不可取
- 不一定所有调用原函数都需要更改
-
新增一个函数 – 不可取
- 需要改 原来调用 house()的代码
装饰器 在不改变原函数名、原函数体 的情况下,对函数功能进行修改
# 完整
def decrator(func): # 定义一个装饰器
a = 100
print('wrapper 外层打印 仍然 执行 ')
def wrapper(): # 包装 装饰
print(' wrapper print a :', a)
func()
print(' 装饰器在原函数的基础上,增加了一个 a:{} 的输出 '.format(a))
print('即使不调用,由于@decrator,wrapper 外层打印 仍然执行 ')
return wrapper
# 使用装饰器
@decrator
def house():
print(' house() :i am 毛坯房, 原函数,保持原功能')
# house()
- @decrator 步骤分析
- 将其下方函数,作为参数 传给decrator()
- 底层 默执行decrator()函数,里面的代码
- 执行到 wrapper(), 加载wrapper内容(未执行)
- 最后 return wrapper
- 默认 同名的house 接收 返回的wrapper
- 打印 wrapper 地址id
- 打印 此时的 新house 地址id
- 下面的新house 即为 wrapper, 其中调用了原house
带有参数的 原函数
- wrapper 也传入同样参数即可:
def decrator(func): # 定义一个装饰器
def wrapper(x): # 包装 装饰
func(x) # 调用被装饰函数,保持其原功能
print(' wrapper print a :', a)
return wrapper
万能 传入参数
- 可变参数
def decrator(func): # 定义一个装饰器
def wrapper(*args, **kwargs): # 包装 装饰
func(*args, **kwargs) # 调用被装饰函数,保持其原功能
print(' wrapper print a :', a)
return wrapper
两层装饰器
@decrator2
@decrator1
house()
首先 近的decrator1 生效,
然后 decrator2 生效
- 可以分析:
- decrator2 先装饰完
- decrator1 装饰 被 decrator2 装饰过的house
- 调用的是 被 decrator1 装饰过的 house
- 相当于 func(func1(func2()))
装饰器 自带 参数
- 只要装饰器自带参数
- 两层装饰器!
def decrator_outer(a): # 接收 装饰器 参数
# 原 装饰器
def decrator(func): # 接收 函数
def wrapper(*args, **kwargs): # 接收 函数参数
func(*args, **kwargs)
print(a)# 调用被装饰函数,保持其原功能
return wrapper
# 返回原 装饰器
return decrator
@decrator_outer(3)