python进阶,在第一期的基础上做了极大的优化,整体更加美观易懂
如果是新手强烈建议代码拿去一步步调试,看是怎么运行的。
定义:就是给已有函数增加额外功能,它本质就是一个闭包函数(闭包特点:
a、函数嵌套
b、内部函数使用了外部函数的变量或参数
c、外部函数返回了内部函数)
功能特点:
a、不修改已有函数的源代码
b、不修改已有函数的调用方式
c、给已有函数增加额外的功能
装饰器的构成条件:闭包的基础上, 外部函数的参数有且只有一个并且是函数类型的闭包是装饰器
# 定义装饰器
# 加一个登陆成功的提示
def waibu(func):
def neibu():
func()
print("登录成功")
return neibu
# 装饰器的语法糖写法: @装饰器名字,完成对已有函数的装饰
@ waibu
def comment():
print("请输入密码:")
# print("登录成功")
comment()
# 结果:
>>> 请输入密码:
>>> 登录成功
写法2(不用语法糖)
def waibu(func):
def neibu():
func() # func()函数其实是已有函数comment在调用
print("登录成功")
return neibu
# 装饰器的语法糖写法: @装饰器名字,完成对已有函数的装饰
# @ waibu
def comment():
print("请输入密码:")
# print("登录成功")
comment = waibu(comment) # 使用@装饰或者是通过传参将两段函数相链接 waibu(comment) = neibu = new_func
# 不修改已有函数的调用方式
# new_func()
comment() # comment()是neibu在调用
# 结果:
>>> 请输入密码:
>>> 登录成功
装饰器的使用场景: 定义一个装饰器统计函数执行的时间
import time # 导入time模块
# print(time.time()) # 获取的是从1970年1月1日 0:0:0到现在的时间差
def waibu(func):
def neibu():
# 统计work函数的获取时间
# 获取函数执行前的时间
qian = time.time()
func() # function()是已有函数work()在调用
# 获取函数执行后的时间
hou = time.time()
print(f"总计用时:{hou - qian}")
return neibu
@ waibu # 等价于外部函数 work = waibu(func)
def work(): # 打印0到9999
for i in range(10000):
print(i)
# work = waibu()
work()
# 结果:
>>> 0
>>> 1
>>> ......
>>> 4999
>>> 5000
>>> ......
>>> 9998
>>> 9999
>>> 总计用时:0.044999122619628906
通用装饰器:装饰任意的函数
def waibu(func):
# 内部函数的类型和被装饰的的类型保持一致
def neibu(a, b):
print("正在执行加法")
func(a, b)
return neibu
# @ waibu
def add_num(num1 , num2):
print(f"结果是:{num1 + num2}")
add_num = waibu(add_num)
add_num(3, 5)
# 结果:
>>> 正在执行加法
>>> 结果是:8
def waibu(func):
def neibu(a, b):
# 内部函数的类型和被装饰函数的类型保持一致
num = func(a, b)
return num
return neibu
# @ waibu
def add_num1(num1, num2):
result = num1 + num2
return result
add_num1 = waibu(add_num1)
print(add_num1(3, 5))
# 结果:
>>> 8
def waibu(func):
def neibu(*a, **b):
# 内部函数的类型和被装饰函数的类型保持一致
num = func(*a, **b)
return num
return neibu
# @ waibu
def add_num1(*args, **kwargs):
# *args:当传入的这个参数个数未知,且不需要知道参数名称时 *args:可以理解为长度不固定的列表。
# **kwargs 当传入的参数个数未知,但需要知道参数的名称时(字典)**kwargs:可以理解为长度不固定的字典
result = 0
for i in args:
result += i
for i in kwargs.values(): # .values()提取值
result += i
return result
result = add_num1(1, 3, 6, 8)
result = add_num1(1, 3, 6, age=18)
print(result)
# 结果:
>>> 28
def dec(func):
def inner(*a, **b):
num = func(*a, **b)
return num
return inner
@ dec
def show():
return "嘿嘿"
print(show())
# 结果:
>>> 嘿嘿
多个装饰器的使用: 多个装饰器装饰一个已有函数
需求:人生苦短,我学python,
人生苦短我学python
,再加def waibu_p(func):
def neibu():
u1 = ""
+func()+"" # dunc在调用conten
return u1
return neibu
def waibu_div(func):
def neibu():
u1 = ""+func()+"" # dunc在调用conten
return u1
return neibu
@ waibu_div
@ waibu_p
def conten():
return "人生苦短,我学python"
print(conten())
# 结果:
>>> <div><p>人生苦短,我学python</p></div>
# 装饰过程,waibu_div(waibu_p(conten)),由内到外,先执行内部,再执行外部
带有参数的装饰器: 就是使用装饰器装饰函数的时候可以传入指定参数
def waibu(func):
def neibu(c, d):
func(c, d)
return neibu
@waibu
def add_num(a, b):
result = a + b
print(result)
add_num(2, 5)
@waibu
def add_num(a, b):
result = a - b
print(result)
add_num(2, 5)
结果:
>>> 7
>>> -3
def a(flag):
def waibu(func):
def neibu(c, d):
if flag == "+":
print("正在执行加法计算...")
elif flag == "-":
print("正在执行减法计算...")
func(c, d)
return neibu
return waibu
@a("+")
def add_num(a, b):
result = a + b
print(result)
add_num(2, 5)
@a("-")
def add_num(a, b):
result = a - b
print(result)
add_num(2, 5)
结果:
>>> 正在执行加法计算...
>>> 7
>>> 正在执行减法计算...
>>>-3
语法格式: @装饰器(参数,,,,,)