闭包函数与解释器详细讲解
闭包函数简介
闭包函数
1.定义在函数内部的函数(函数的嵌套)
2.内部函数使用的了外部函数名称空间的名字
"""
只有满足以上两种特征的函数次才可以称为闭包函数
"""

def func(name):
def index():
print(name)
return index
res = func('make')
print(res)
res()
res1 = func('jason')
print(res1)
res1()
闭包函数的实际应用
"""
实际应用的场景 简单点说就是给函数传参
"""
1.第一种给函数体代码传值的方式:是通过形参给函数传值
def func(name):
print(name)
func('make')
2.第二种给函数体代码传值的方式:闭包函数
def func(name):
def index():
print(name)
return index
res = func('make')
res()
res1 = func('jason')
res1()
装饰器简介
1.装饰器的本质
器:代表函数的意思。装饰器本质就是在不改变被装饰对象的 '调用方法'和'内部代码'的情况下给其添加附加功能
被装饰函数感受不到装饰器的存在
2.装饰器的原则
不能修改被装饰的函数的代码体结构
不能修改被装饰的函数的调用方式
(对修改说no 对扩展yes)
3.知识储备
import time
print(time.time())
'''
上述为时间戳(单位:秒):此刻 距离 1970年1月1日0时0分0秒 所经历的秒速
'''
可以用此测算出代码运行多长时间结束
import time
start_time = time.time()
for i in range(999):
print(i)
end_time = time.time()
time1 = end_time - start_time
print(time1)
time.sleep()
例如:
time.sleep(10)
print(999)
装饰器前期推导
1.
import time
def func():
time.sleep(5)
print('from func')
'统计下函数func中执代码执行的时间'
start_time = time.time()
func()
end_time = time.time()
print(end_time-start_time)
"""
此代码缺陷:
如果需要多次调用函数 需要重复的编写代码
比较繁琐
故可以把此代码封装成函数
"""
2.
import time
def func():
time.sleep(5)
print('from func')
'统计下函数func中执代码执行的时间'
def time1():
start_time = time.time()
func()
end_time = time.time()
print(end_time-start_time)
time1()
time1()
time1()
"""
封装成函数后虽然可以多次调用 但是每次调用的都是函数func的值 如果有多个不同函数需要统计代码运行时间 此代码措施不能兼备
故
给函数体添加形参(动态传参)
"""
3.
import time
def foo():
time.sleep(3)
print('from foo')
def func():
time.sleep(5)
print('from func')
def time1(unknown):
start_time = time.time()
unknown()
end_time = time.time()
print(end_time-start_time)
time1(foo)
time1(func)
"""
看似好像只要在前定义好函数 后面就可以随意调用函数 获取运行时间 其实我们刚才定义的函数都是没有形参的
代码体中的函数名 unknown() 这个括号里面是固定没有参数的
def func1(a):
time.sleep(3)
print('from func1')
get_time(func1) # 报错
如果在定义函数的时候 写了形参 上述代码
调用时就会报错
因为代码体里的 unknown() 前面的函数名可以随意的更改 但是()已经写死了 固定是不可以写入参数的 不过也可以解决
措施:
可以在括号里写入 可变长参数 (*args,**kwargs) 但是目前这种代码结构不支持这样写入(暂且忽略)
还有一点:
上面的调用方式已经改变了 被装饰的函数的调用方式 违背装饰器的原则
解决措施:
装饰器推导流程
"""
装饰器的各种版本
"""前面讲到 传入的函数一旦填写了参数 代码运行起来就会报错 用(*args,**kwargs)上述结构无法运行也会报错
"""
"""
下面介绍解决措施 针对有参无参函数如何兼容
"""
2.无参函数调用方式
import time
def foo(unknown):
def time1():
start_time = time.time()
unknown()
end_time = time.time()
print(end_time-start_time)
return time1
def home():
time.sleep(3)
print('from home')
home = foo(home)
home()
def index():
time.sleep(4)
print('from index')
index = foo(index)
index()
2.有参函数调用方式
3.装饰器的完整版
import time
def foo(unknown):
def time1(*args, **kwargs):
start_time = time.time()
res = unknown(*args, **kwargs)
end_time = time.time()
print(end_time-start_time)
return res
return time1
def func(name = 'jason',age = 18):
time.sleep(4)
print(name, age)
return '执行func函数的返回值'
func = foo(func)
res = func()
print(res)
def home(a,b):
time.sleep(3)
print('from home')
return '执行home函数的返回值'
home = foo(home)
res = home(1,2)
print(res)
装饰器模板
import time
def foo(unknown):
def time1(*args, **kwargs):
start_time = time.time()
res = unknown(*args, **kwargs)
end_time = time.time()
print(end_time-start_time)
return res
return time1
def func(name = 'jason',age = 18):
time.sleep(4)
print(name, age)
return '执行func函数的返回值'
func = foo(func)
res = func()
print(res)
def home(a,b):
time.sleep(3)
print('from home')
return '执行home函数的返回值'
home = foo(home)
res = home(1,2)
print(res)
装饰器的固定模板
from functools import wraps
def outer(func_name):
@wraps(func_name)
def inner(*args, **kwargs):
print('执行被装饰对象之前可以做的额外操作')
res = func_name(*args, **kwargs)
print('执行被装饰对象之后可以做的额外操作')
return res
return inner
"""
执行home函数之前需要添加校验用户身份的功能
"""
import time
@outer
def home():
'''我是home函数 我要热死了!!!'''
time.sleep(1)
print('from home')
return 'home返回值'
home()
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)