@在Python中可以用来修饰函数或者类,但是更多的是修饰函数,用来在不改变即有函数代码的情况下,给函数增加新的功能。(或者类)
比如我们在使用Flask开发web应用的时候,在方法前就使用@app.route('/wanmait')来给方法添加web请求路由映射。
如何创建自己的@修饰符呢?
首页@修饰符就是函数。
我们把用@修饰符 修饰的函数叫做被修饰函数。
比如有个函数:
def wanmait_fun1(): print("在万码学堂学习编程") def wanmait_fun2(): print("在万码学堂学习Python") wanmait_fun1() wanmait_fun2()
执行结果为:
在万码学堂学习编程 在万码学堂学习Python
现在我们想自己定义个修饰符,来修饰这两个函数,以改变一点什么。
现在我们定义一个最简单的符合修饰符要求的函数如下:
def test(func): def wrapper(): print("wanmait.com test...") return wrapper @test def wanmait_fun1(): print("在万码学堂学习编程") @test def wanmait_fun2(): print("在万码学堂学习Python") wanmait_fun1() wanmait_fun2()
执行结果:
wanmait.com test... wanmait.com test...
注意这个test()函数的参数func,实际在@后的修饰符就是要调用执行的函数,并且会将被修饰函数传递给这个修饰函数,所以要求这个修饰符函数必须要接受一个函数参数。我们的目标是这个参数应该传递进来一个函数对象。(Python中函数也是对象,可以传递。)
这个函数的返回值必须也是一个函数(在这个函数内部定义的函数),这个返回的函数就是最终使用修饰符之后执行的函数。
所以上面的代码使用@test修饰后,实际执行的是test函数中定义的wrapper函数。
我们当然不希望这样,我们希望还是要执行(当然执不执行也还是由程序逻辑来决定)被修饰函数并且正确的接受所有参数,那如何处理呢?
我们只要在wrapper函数定义上允许任何参数传入即可,使用可变参数和可变关键字参数。
def goto_wanmait(func): def wrapper(*args,**kwargs): print("现在就去万码学堂!") func(*args,**kwargs) print("在wanmait.com学习很快乐!") return wrapper
这个函数的返回值是一个函数(在这个函数内部定义的函数),这个函数可以接受任意参数(无参,可变参数、可变关键字参数)
func(*args,**kwargs)
这样代码确定了调用传递进来的函数(也就是被修饰函数),而且将任意参数解构传递进去(这种形态保证了一定符合被修饰函数的参数定义)
从而完成了@修饰符这件事的逻辑。
@goto_wanmait def wanmait_fun1(): print("在万码学堂学习编程") @goto_wanmait def wanmait_fun2(): print("在万码学堂学习Python") wanmait_fun1() wanmait_fun2()
执行结果:
现在就去万码学堂! 在万码学堂学习编程 在wanmait.com学习很快乐! 现在就去万码学堂! 在万码学堂学习Python 在wanmait.com学习很快乐!
到这里我们顺利定义了我们自己的修饰符,假如想要给修饰符传递参数怎么办呢?
那就只要再增加一层来接受参数调用即可,注意这时候@修饰符后加了()和参数来使用修饰符,实际上这时候是调用了这个修饰符函数,要求返回的结果必须是刚才我们所描述的形式(就是能接受一个func函数作为参数并返回一个函数来执行),代码如下:
def goto_wanmait(name='无名'): def wrapperoutter(func): def wrapper(*args,**kwargs): print(f"【{name}】现在就去万码学堂!") func(*args,**kwargs) print(f"【{name}】在wanmait.com学习很快乐!") return wrapper return wrapperoutter @goto_wanmait(name="小明") def wanmait_fun1(): print("在万码学堂学习编程") @goto_wanmait(name="小红") def wanmait_fun2(): print("在万码学堂学习Python") wanmait_fun1() wanmait_fun2()
运行结果:
【小明】现在就去万码学堂! 在万码学堂学习编程 【小明】在wanmait.com学习很快乐! 【小红】现在就去万码学堂! 在万码学堂学习Python 【小红】在wanmait.com学习很快乐!
这就是Python中的修饰符定义,很简洁又很实用的Python装饰器。
0条评论
点击登录参与评论