今日大纲
1.函数的有用信息
2.带参数的装饰器
3.多个装饰器装饰一个函数
1.函数的有用信息
在函数体中用"""解释内容"""
print(login.__name__) 打印函数名称
print(login.__doc__) 打印函数体的解释内容
例1:
def login(username, password):
"""
此函数是一个登陆函数
:param username: 输入用户名
:param password: 输入密码
:return: 登录成功返回"登录成功!",否则返回"登录失败!"
"""
if username == "david" and password == "123456":
return "登录成功!"
else:return "登录失败!"
print(login.__name__)
print(login.__doc__)
username1 = input("请输入账号:").strip()
password1 = input("请输入密码:").strip()
print(login(username1, password1))
例2:当遇到装饰器时,要打印被装饰函数的原函数名和原注释内容时
import time
from functools import wraps
def wrapper(f):
@wraps(f)
def inner(*args,**kwargs):
"""被装饰前的操作"""
start_time = time.time()
time.sleep(0.3)
ret = f(*args,**kwargs)
end_time = time.time()
"""被装饰后的操作"""
print("函数执行时间是{}s".format(end_time-start_time))
return ret
return inner
@wrapper
def func1(a,b):
"""
此函数的功能是打印传入的参数
:param a: 任意数据类型
:param b: 任意数据类型
:return: "666......"
"""
print(a, b)
return "666......"
print(func1.__name__) # 打印被装饰的函数的函数名
print(func1.__doc__) # 打印被装饰的函数的注释内容
print(func1(11, 22))
2.带参数的装饰器
情景:要为多个函数装上装饰器,因用户需要,需要实现可自主改变是否需要装饰的功能
import time
flag = True
def wrapper_out(flag):
def wrapper(f):
def inner(*args,**kwargs):
"""被装饰前的操作"""
if flag:
start_time = time.time()
time.sleep(0.3)
ret = f(*args,**kwargs)
end_time = time.time()
"""被装饰后的操作"""
print("函数执行时间是{}s".format(end_time-start_time))
return ret
else:
ret = f(*args, **kwargs)
return ret
return inner
return wrapper
flag1 = True #只需要改变此处的flag的值即可对所有被装饰的函数选择是否需要被装饰,也可单独对某个函数传入特点的flag
@wrapper_out(flag1) #1,先执行wrapper_out(flag1)得到返回值wrapper;2,@wrapper 等价于 func1 = wrapper(func1)
def func1(*args,**kwargs):
print()
print(args)
print(kwargs)
return "666......"
@wrapper_out(flag1)
def func2(*args,**kwargs):
print()
print(args)
print(kwargs)
return "777....."
@wrapper_out(flag1)
def func3(*args,**kwargs):
print()
print(args)
print(kwargs)
return "888......"
print(func1(11, 22))
print(func2(333,444,555,name = "david",age = 18))
print(func3(*[111,222,333],*[444,555,666]))
补充1:局部只能引用全局的变量,不能修改,修改则需要global
count = 1
def func4():
count = count + 1
print(count)
func4() #报错,原因:count = count + 1 此处,count无法理解是引入的全局变量,还是重新形成的新变量
补充2:子函数只能引用父函数的变量,不能修改,如果要修改,nonlocal。
def func4():
count = 3
def inner():
count = count + 1
print(count)
func4() #报错
3.多个装饰器装饰一个函数
def wrapper1(f): #2,f = func
def inner1(*args,**kwargs):
print("111......") #12,111......
ret = f(*args,**kwargs) #13,等价于 func($-_-$","$-_-$") #16 ret = "NB!"
print("......111") #17......111
return ret #18
return inner1 #3,返回inner1
def wrapper2(f): #6,f = inner1
def inner2(*args,**kwargs): #9 *args聚合 args = ("$-_-$","$-_-$")
print("222......") #10, 222......
ret = f(*args,**kwargs) #11.f("$-_-$","$-_-$") 等价于 inner1("$-_-$","$-_-$") #19 ret = "NB!"
print("......222") #20 .......222
return ret #21 ret = "NB!"
return inner2 #7,返回inner2
@wrapper2 #5,func = wrapper2(func) 等于 func = wrapper2(inner1) 等于 func = inner2
@wrapper1 #1,首先执行靠近被装饰函数的装饰器 func = wrapper1(func) #4,func = inner1
def func(a, b): #a = "$-_-$" b = "$-_-$"
print("{}...666...{}".format(a, b)) #14,打印该语句
return "NB!" #15
print(func("$-_-$","$-_-$")) #8,等价于inner2("$-_-$","$-_-$") #22 打印 NB!
执行结果:
222......
111......
$-_-$...666...$-_-$
......111
......222
NB!
执行结果的规律:类似于大箱子里套个小箱子,有几层套几层,最里面是被装饰的函数。