您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息
免费发信息
三六零分类信息网 > 常州分类信息网,免费分类信息发布

python自动化装逼指南1——装饰器详解

2024/2/4 7:15:12发布17次查看
这篇文章由柠檬班python全栈自动化学员
重庆--圆滚滚童鞋分享的一篇技术共享文章。
话不多说,直接上文章
一. 装饰器原则:
1. 不能修改被装饰函数的源代码
2. 不能修改被装饰函数的调用方法
二. 知识储备
1. 函数及变量
2. 高阶函数(满足一个即可)
2.1 函数名做函数实参
# import time
# def bar():
# time.sleep(3)
# print('in the bar')
#
# def test1(func):
# start_time=time.time()
# func() #run bar
# stop_time=time.time()
# print(the func run time is %s %(stop_time-start_time))
#
# test1(bar)
# bar()
可以实现在不改变源代码的情况下,为函数添加功能,但是改变了函数的调用方式
2.2 函数返回值中包含函数名
import time
def bar():
time.sleep(3)
print('in the bar')
def test2(func):
print(func)
return func
# print(test2(bar))
bar=test2(bar)
bar() #run bar
实现了直接通过bar(),不改变函数的调用方式,增加函数的功能
3. 嵌套函数
在一个函数的函数体内,用def去声明一个函数,而不是其调用他
def grandpa():
x = 1
def dad():#在这里只是声明了一个函数,但是没有调用他,所以最后什么都不打印
x =2
def son():
x = 3
print(x)
son()
#dad()
grandpa()
三. python的内存回收机制:
python的解释器中有一个引用计数的概念,python通过这个引用机制来实现内存的回收
四. 匿名函数
calc = lambda x:x*3
print(calc(3))
#结果为9
匿名函数没有函数名,声明后会立马被回收掉,但是将其赋值给一个变量之后,就不会被立马回收掉
五. 装饰器演化进程
1. 利用嵌套函数、高阶函数实现装饰器
1.1
import time
def deco(func):
def timer():
start_time = time.time()
func()
end_time = time.time()
print([32;1mthe func runs %s%(end_time-start_time))
return timer
def test1():
time.sleep(1)
print(in the test1)
test1 = deco(test1)
test1()
这种方式多了test1=deco(test1)的步骤
1.2 python@语法糖
python解释器提供了一个语法糖,来代替test1 = deco(test1)的功能
import time
def deco(func):
def timer():
start_time = time.time()
func()
end_time = time.time()
print([32;1mthe func runs %s%(end_time-start_time))
return timer
@deco#等于是执行了test1 = deco(test1)
def test1():
time.sleep(1)
print(in the test1)
test1()
1.3 带参数装饰器实现
但是上面的装饰器只是适用于无参函数,对于有参函数就会报错,要想实现对带参函数实现装饰器功能,需要在装饰器函数中带上参数,注意@test就是执行了test1=deco(test1),实际上是执行了嵌套的timer函数,所以在timer函数中带*args,**kwags参数,就可以实现利用装饰器修饰所有的带参以及不带参函数
import time
def timer(func):
def deco(*arg, **kwargs):
start_time = time.time()
func(*arg, **kwargs)
end_time = time.time()
print([34;1mthe func runs %s%(end_time-start_time))
return deco
@timer #等于是执行了test1 = timer(test1)
def test1():
time.sleep(0.5)
print(in the test1)
@timer
def test2(name):
time.sleep(0.5)
print(in the test2, name)
test1()
test2(gupan)
1.4 python装饰器实现选择执行
如果遇到遇到如下的场景,对于一个网站来说,如果是用户普通的登陆,只需要调用本地的认证服务器进行判断,如果涉及到充值等金钱相关业务,就需要调用第三方的认证接口,进行身份信息的验证,这就需要在定义引用装饰器的时候就传入参数@deco(auth_type = local),但是在讲解装饰器时,我们看到,函数第一层已经传入了函数名作为参数,第二层传入业务函数的参数,这样就需要我们再添加一层
python的解释器对@语法糖作出如下规定
如果@deco(auth_type=lcoal),local传入了最外面一层,第二层传入其修饰的函数的函数名,第三层传入了其所修饰函数实参
import time
user,passwd = 'alex','abc123'
def auth(auth_type):#先传入auth_type参数
print(auth func:,auth_type)
def outer_wrapper(func):#传入所修饰函数的函数名
def wrapper(*args, **kwargs):#传入函数被装饰函数实参
print(wrapper func args:, *args, **kwargs)
if auth_type == local:
username = input(username:).strip()
password = input(password:).strip()
if user == username and passwd == password:
print([32;1muser has passed authentication[0m)
res = func(*args, **kwargs) # from home
print(---after authenticaion )
return res
else:
exit([31;1minvalid username or password[0m)
elif auth_type == ldap:
print(搞毛线ldap,不会。。。。)
return wrapper
return outer_wrapper
def index():
print(welcome to index page)
@auth(auth_type=local) # home = wrapper()
def home():
print(welcome to home page)
return from home
@auth(auth_type=ldap)
def bbs():
print(welcome to bbs page)
index()
print(home()) #wrapper()
bbs()
常州分类信息网,免费分类信息发布

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录