函数(三)
闭包函数
闭包,又称闭包函数或者闭合函数,其实和前面讲的嵌套函数类似,不同之处在于,闭包中外部函数返回的不是一个具体的值,而是一个函数。一般情况下,返回的函数会赋值给一个变量,这个变量可以在后面被继续执行调用。 # 闭包函数的两大特征
1.闭:定义在函数内部的函数
2.包:内部函数使用了外层函数名称空间中的名字
def outer():
x = 999
def inner():
print('from outer>>>inner',x)
return inner
x = 666
res = outer()
res() # 结果999
闭包函数的实际应用
'''闭包函数是给函数体传参的另外一种方式'''
# 函数体传参的方式有形参 闭包
# 方式1:形参
def info(username)
print(usernam)
# 函数体需要什么参数在形参在写对应的就行
info('张三')
# 方式2:闭包
def outer(username):
# username = 'jason'
def index():
print(username) # 永远使用的都是jason
return index
res = outer('kevin') # 形参username与值kevin临时绑定 >>>:outer局部名称空间中
res()
res1 = outer('jason') # 形参username与值kevin临时绑定 >>>:outer局部名称空间中
res1()
装饰器简介
装饰器是 Python 的一个重要基础部分。简单地说:他们是修改或实现其他函数的功能的函数(工具)。他们有助于让我们的代码更简短,也更能体现程序员的基础是否牢固(写的好的就是“装杯”)。大多数初学者不知道在哪儿使用它们,所以我将要分享下,哪些区域里装饰器可以让你的代码更简洁。 """
装饰器并不是一个新的知识点 而是由前两天所有的函数知识点整合到一起的产物
名称空间 函数名 闭包函数...
"""
装饰器的本质
在不改变被装饰对象原有的'调用方式'和'内部代码'
的情况下给被装饰对象添加新的功能
装饰器的原则
对扩展开放
对修改封闭
# 时间戳
import time # 导入模块
# print(time.time()) # 1647568920.168808
'''上述的数字是时间戳:1970年1月1日0时0分0秒距离刚刚代码运行间隔的秒数'''
import time # 导入time模块
def outer(func_name):
def get_time(*args, **kwargs): # 可变长参数
start_time = time.time() # time.time()为时间戳 函数体开始的时间戳
res = func_name(*args, **kwargs) # 执行真正的play函数
end_time = time.time() # 函数体运行结束后的时间戳
print(end_time - start_time) # 两个时间戳的差
# 如何在此处返回真正index函数的返回值
return res #
return get_time
简易版装饰器
# 装饰器有参数的写法
def fly():
time.sleep(2) # 停止2秒
print('两秒真男人!!')
import time # 导入time模块
def outer(func_name):
def get_time(*args, **kwargs): # 可变长参数
start_time = time.time() # time.time()为时间戳 函数体开始的时间戳
func_name(*args, **kwargs) # 执行真正的play函数
end_time = time.time() # 函数体运行结束后的时间戳
print(end_time - start_time) # 两个时间戳的差
return get_time
fly = outer(fly) # 将函数作为实参赋值给
fly() # 相当于get_time()
完整版装饰器
# 有返回值的写法
def fly():
time.sleep(2) # 停止2秒
print('两秒真男人!!')
return '哈哈哈 伟啦'
import time # 导入time模块
def outer(func_name):
def get_time(*args, **kwargs): # 可变长参数
start_time = time.time() # time.time()为时间戳 函数体开始的时间戳
res = func_name(*args, **kwargs) # 执行真正的play函数
end_time = time.time() # 函数体运行结束后的时间戳
print(end_time - start_time) # 两个时间戳的差
# 如何在此处返回真正index函数的返回值
return res #
return get_time
fly = outer(fly) # 将函数作为实参赋值给
res = fly()
print(res) # 返回值: 哈哈哈 伟啦
装饰器模板
对于装饰器不太理解的其实不用太过于担心,只要记住下面的这个模板直接使用就行了 '''编写装饰器其实有一套固定的代码 不需要做任何理解'''
def outer(func_name): # func_name用于接收被装饰的对象(函数)
def inner(*args, **kwargs):
print('执行被装饰函数之前 可以做的额外操作')
res = func_name(*args, **kwargs) # 执行真正的被装饰函数
print('执行被装饰函数之后 可以做的额外操作')
return res # 返回真正函数的返回值
return inner
装饰器语法糖
'''可以使代码更整洁'''
语法糖的用法就比较简单了,只要把编写好的装饰器
在函数前或某些代码前一行写 @ + 装饰器名(装饰器的外层函数的函数名)
import time # 导入time模块
def outer(func_name):
def get_time(*args, **kwargs): # 可变长参数
start_time = time.time() # time.time()为时间戳 函数体开始的时间戳
res = func_name(*args, **kwargs) # 执行真正的play函数
end_time = time.time() # 函数体运行结束后的时间戳
print(end_time - start_time) # 两个时间戳的差
# 如何在此处返回真正index函数的返回值
return res #
return get_time
# 装饰器语法糖
@outer # @ + 装饰器的外层函数的函数名
def play():
time.sleep(1) # 停止一秒钟
print('玩个寄吧游戏')
return '你给我叫爸爸!'
res = play()
print(res) # 打印返回值res 你给我叫爸爸!
装饰器修复技术
函数的装饰器修复技术,可以使被装饰的函数在增加了新的功能的前提下,不改变原来函数的函数名,还继续使用原函数的注释内容。让人很难发现是被装饰器修改过函数名。 # 做到比真的还要真 但是本质其实没有变
'''
装饰器修复技术关键在于 from functools import wraps
和 @wraps() 的连用
'''
import time # 导入time模块
from functools import wraps
def outer(func_name):
@wraps(func_name)
def get_time(*args, **kwargs): # 可变长参数
start_time = time.time() # time.time()为时间戳 函数体开始的时间戳
res = func_name(*args, **kwargs) # 执行真正的play函数
end_time = time.time() # 函数体运行结束后的时间戳
print(end_time - start_time) # 两个时间戳的差
# 如何在此处返回真正index函数的返回值
return res #
return get_time
# 装饰器语法糖
@outer # @ + 装饰器的外层函数的函数名
def play():
'''玩游戏不?'''
time.sleep(1)
print('玩个寄吧游戏')
return '你给我叫爸爸!'
# help可以查看指定函数的注释信息
help(play) # 没加前get_time(*args, **kwargs)
# 加了之后play() 玩游戏不?
本文来自博客园,作者:{Mr_胡萝卜须},转载请注明原文链接:https://www.cnblogs.com/Mr-fang/p/16022912.html