博观而约取,厚积而薄发。这篇文章主要讲述Python闭包与装饰器相关的知识,希望能为你提供帮助。
title: "python闭包与装饰器"
descriptime: "Python闭包与装饰器"
keywords: ["python","decorate"]
tags: ["Python"]
categories: ["Python"]
draft: false
闭包
定义:内部函数对外部函数作用域里变量的引用
- 函数内的属性都是有生命周期的,只在函数运行期间存活 闭包内的闭包函数私有化了变量,完成了数据的封装。
- 闭包指的是延伸了作用域的函数,其中包含函数定义体中引用、但是不在定义体中定义的非全局变量。函数是不是匿名没有关系,关键是它能访问定义体之外定义的非全局变量。
- 在一个内部函数中,对外部作用域的变量进行引用,(并且一般外部函数的返回值为内部函数),那么内部函数就被认为是闭包
- 闭包是一种函数,它会保留定义函数时存在的自由变量的绑定,这样调用函数时,虽然定义作用域不可用了,但是仍能使用那些绑定。
def f1():
x = hello
def f2():
print(x + world)
return f2
x = f1() #此时x就相当于f2
x() #相当于 f2()
以上示例中,返回
return f2()
就叫做闭包带参数的闭包
def f1():
x = hello
def f2(y):
print(x+y)
return f2
f1()( world)#f1() ==> f2
升级一下小示例,外函数也是参数的情况
some_list = [1,2,3]
def f1(obj):
def f2():
obj[0] += 1
print(obj)
return f2
jia = f1(some_list)
jia() #[2, 2, 3]
jia() #[3, 2, 3]
装饰器
是python的一种语法糖。一般用来在不更改原有函数的基础上,对原函数添加新的功能。
不含参数的装饰器一般示例如下
@some_func
def func_example():
pass
其中,func_example表示被装饰函数,some_func表示装饰器。
@some_func
即相当于some_func(func_example)()
示例1:
def wen(func):
print(Who are you ?)
return func
@wen
def func1():
print("Im Gourds")
以上示例虽然没有调用
func1()
不过却输出了Who are you ?
。说明: 装饰器在加载模块时立即执行,而被装饰的函数只在明确调用时运不过显然这不是我想要的结果,我希望只有调用
func1()
的时候才问我,示例2就对了示例2:
def wen(func):
def inner():
print(Who are you ?)
func()
return inner
@wen
def func1():
print("Im Gourds")
func1()
实际,这个示例中
func1()
等同于wen(func1)()
示例3:给睡觉加个统计,看看睡了多久
import random
import time
def wait_how_long(func):
def inner():
ts = time.time()
func()
td = time.time()
print(Time is :.2s.format(td-ts))
return inner
@wait_how_long
def sleep_a_moment():
print(sleeping...)
sj = random.randint(1,5)
time.sleep(sj)
print(awake)
sleep_a_moment()
带参数的被装饰函数
示例:给睡觉时间上限改成可调整的
import random
import time
def wait_how_long(func):
def inner(*args,**kwargs):
ts = time.time()
func(*args,**kwargs)
td = time.time()
print(Time is :.2s.format(td-ts))
return inner
@wait_how_long
def sleep_a_moment(num):
print(sleeping...)
sj = random.randint(1,num)
time.sleep(sj)
print(awake)
sleep_a_moment(5)
示例:牵涉返回值的情况,加上
import random
import time
def wait_how_long(func):
def inner(*args,**kwargs):
ts = time.time()
rst = func(*args,**kwargs) #需要将被装饰返回值存起来
td = time.time()
print(Time is :.2s.format(td-ts))
return rst #结束时返回
return inner
@wait_how_long
def sleep_a_moment(num):
print(sleeping...)
sj = random.randint(1,num)
time.sleep(sj)
return music #当然,前提是被装饰函数有返回值
x = sleep_a_moment(5)
print(x)
【Python闭包与装饰器】示例:多个装饰器的执行情况
def test1(func):
def wrapper(*args, **kwargs):
print(before test1 ...)
func(*args, **kwargs)
print(after test1 ...)
return wrapper #返回内层函数的引用
def test2(func):
def wrapper(*args, **kwargs):
print(before test2 ...)
func(*args, **kwargs)
print(after test2 ...)
return wrapper #返回内层函数的引用
@test2
@test1
def add(a, b):
print(推荐阅读
- #yyds干货盘点# C#中类的override和virtual
- 个推技术实践 | 掌握这两个调优技巧,让TiDB性能提速千倍!
- #yyds干货盘点# mybatis源码解读(executor包(语句处理功能))
- mysql 高级SQL语句
- hudi使用cow生成parquet格式用hive查询的问题
- #yyds干货盘点#RabbitMQ示例6(远程过程调用RPC)
- 老大说(谁要再用double定义商品金额,就自己收拾东西走)
- 第十一节:Springboot整合log4j2日志
- #过年不停更#HarmonyOS自定义JS组件—灵动的锦鲤