测试开发技术网站
博客
设计
设计
开发
Python
测试
unittest
运维
Linux基础应用
CI/CD
CI/CD
数据库
数据库
云计算
云计算
云原生
云原生
爬虫
爬虫
数据分析
数据分析
人工智能
人工智能
登录
注册
Python----Python高级特性-装饰器
收藏本文
作者:redrose2100 类别: 日期:2022-05-10 07:42:16 阅读:1069 次 消耗积分:0 分
[【原文链接】Python----Python高级特性-装饰器](http://devops-dev.com/article/140) [TOC] ![](https://redrose2100.oss-cn-hangzhou.aliyuncs.com/img/a3bb0554-574b-11ee-91ff-0242ac110004.png) # 一 装饰器是函数, ## 1.1 被装饰对象也是函数 装饰器是函数,被装饰对象是函数时,此时装饰器的作用是给被装饰对象的函数做功能增强功能,思想是面向切面编程思想,即在被装饰对象的函数的之前和之后做一些额外处理,而不破坏被装饰函数原有的功能实现,主要有以下几种情况: ### 1.1.1 装饰器无参数,被装饰对象无参数 ```bash def decorator(func): def _decorator(): print("before func......") func() print("after func......") return _decorator @decorator def func(): print("in func()......") if __name__=="__main__": func() ``` 执行结果为: ```bash before func...... in func()...... after func...... ``` ### 1.1.2 装饰器无参数,被装饰对象有参数 ```bash def decorator(func): def _decorator(*args,**kwargs): print("before {name}......".format(name=func.__name__)) func(*args,**kwargs) print("after {name}......".format(name=func.__name__)) return _decorator @decorator def func1(): print("in func1()......") @decorator def func2(a,b): print("in func2()......") print("a={a},b={b}".format(a=a,b=b)) @decorator def func3(a,b,c=10): print("in func3()......") print("a={a},b={b}".format(a=a, b=b)) print("c={c}".format(c=c)) if __name__=="__main__": func1() func2(1,2) func3(1,2,c=100) ``` 运行结果为: ```bash before func1...... in func1()...... after func1...... before func2...... in func2()...... a=1,b=2 after func2...... before func3...... in func3()...... a=1,b=2 c=100 after func3...... ``` ### 1.1.3 装饰器有参数,被装饰对象无参数 ```bash def wrapper(name): def decorator(func): def _decorator(): print("before {name} ,decorator param is {param}".format(name=func.__name__,param=name)) print("before {name}......".format(name=func.__name__)) func() print("after {name}......".format(name=func.__name__)) return _decorator return decorator @wrapper(name="hello world") def func1(): print("in func1()......") if __name__=="__main__": func1() ``` 运行结果为: ```bash before func1 ,decorator param is hello world before func1...... in func1()...... after func1...... ``` ### 1.1.4 装饰器有参数,被装饰器对象有参数 ```bash def wrapper(name): def decorator(func): def _decorator(*args,**kwargs): print("before {name} ,decorator param is {param}".format(name=func.__name__,param=name)) print("before {name}......".format(name=func.__name__)) func(*args,**kwargs) print("after {name}......".format(name=func.__name__)) return _decorator return decorator @wrapper(name="hello world") def func1(): print("in func1()......") @wrapper(name="hello world") def func2(a, b): print("in func2()......") print("a={a},b={b}".format(a=a, b=b)) @wrapper(name="hello world") def func3(a, b, c=10): print("in func3()......") print("a={a},b={b}".format(a=a, b=b)) print("c={c}".format(c=c)) if __name__=="__main__": func1() func2(1,2) func3(1,2,c=100) ``` 运行结果如下: ```bash before func1 ,decorator param is hello world before func1...... in func1()...... after func1...... before func2 ,decorator param is hello world before func2...... in func2()...... a=1,b=2 after func2...... before func3 ,decorator param is hello world before func3...... in func3()...... a=1,b=2 c=100 after func3...... ``` ## 1.2 被装饰器对象是类 被装饰器对象为类时,装饰器的作用是类在初始化的时候做功能增强,即可以在类初始化之前或者之后做一些功能增强,所以下面所说的被装饰对象有无参数是针对类的初始化函数__init__有无参数而言的,主要有以下几种情况: ### 1.2.1 装饰器无参数,被装饰类无参数 ```bash def decorator(cls): def _decorator(): print("before class {name} init......".format(name=cls.__name__)) obj=cls() print("after class {name} init......".format(name=cls.__name__)) return obj return _decorator @decorator class Test(object): def __init__(self): print("in class {name} init function......".format(name=Test.__name__)) def func(self): print("in class {name} func()".format(name=Test.__name__)) if __name__=="__main__": test=Test() test.func() ``` 运行结果如下: ```bash before class Test init...... in class _decorator init function...... after class Test init...... in class _decorator func() ``` ### 1.2.2 装饰器无参数,被装饰类有参数 ```bash def decorator(cls): def _decorator(*args,**kwargs): print("before class {name} init......".format(name=cls.__name__)) obj=cls(*args,**kwargs) print("after class {name} init......".format(name=cls.__name__)) return obj return _decorator @decorator class Test(object): def __init__(self,a,b=10): print("in class {name} init function......".format(name=Test.__name__)) print("a={a},b={b}".format(a=a,b=b)) def func(self): print("in class {name} func()".format(name=Test.__name__)) if __name__=="__main__": test=Test(2,20) test.func() ``` 执行结果如下: ```bash before class Test init...... in class _decorator init function...... a=2,b=20 after class Test init...... in class _decorator func() ``` ### 1.2.3 装饰器有参数,被装饰类无参数 ```bash def wrapper(name="hello world"): def decorator(cls): def _decorator(): print("before class {name} init......".format(name=cls.__name__)) obj=cls() print("after class {name} init......".format(name=cls.__name__)) return obj return _decorator return decorator @wrapper("hello world") class Test(object): def __init__(self): print("in class {name} init function......".format(name=Test.__name__)) def func(self): print("in class {name} func()".format(name=Test.__name__)) if __name__=="__main__": test=Test() test.func() ``` 执行结果如下: ```bash before class Test init...... in class _decorator init function...... after class Test init...... in class _decorator func() ``` ### 1.2.4 装饰器有参数,被装饰类有参数 ```bash def wrapper(name="hello world"): def decorator(cls): def _decorator(*args,**kwargs): print("before class {name} init......".format(name=cls.__name__)) obj=cls(*args,**kwargs) print("after class {name} init......".format(name=cls.__name__)) return obj return _decorator return decorator @wrapper("hello world") class Test(object): def __init__(self,a,b=10): print("in class {name} init function......".format(name=Test.__name__)) print("a= {a} b={b}".format(a=a,b=b)) def func(self): print("in class {name} func()".format(name=Test.__name__)) if __name__=="__main__": test=Test(2,b=20) test.func() ``` 运行结果如下: ```bash before class Test init...... in class _decorator init function...... a= 2 b=20 after class Test init...... in class _decorator func() ``` ## 1.3 被装饰对象是类中的方法 当被装饰对象是类中的方法时,装饰器的作用是对类中的方法进行功能加强,此时需要注意的是装饰器的内层函数需要增加一个self形参 ### 1.3.1 装饰器无参数,被装饰类中的方法无参数 ```bash def decorator(func): def _decorator(self): print("before method {name}......".format(name=func.__name__)) obj = func(self) print("after method {name} ......".format(name=func.__name__)) return obj return _decorator class Test(object): def __init__(self, a=1, b=10): self.a = a self.b = b @decorator def func(self): print("in class {name} func()".format(name=Test.__name__)) print("a={a} b={b}".format(a=self.a, b=self.b)) if __name__ == "__main__": test = Test() test.func() ``` 执行结果如下: ```bash before method func...... in class Test func() a=1 b=10 after method func ...... ``` ### 1.3.2 装饰器无参数,被装饰类中的方法有参数 ```bash def decorator(func): def _decorator(self,*args,**kwargs): print("before method {name} ......".format(name=func.__name__)) obj=func(self,*args,**kwargs) print("after method {name} ......".format(name=func.__name__)) return obj return _decorator class Test(object): def __init__(self,a=1,b=10): self.a=a self.b=b @decorator def func(self,c,d=20): print("in class {name} func()".format(name=Test.__name__)) print("a={a} b={b}".format(a=self.a,b=self.b)) print("c={c} d={d}".format(c=c,d=d)) if __name__=="__main__": test=Test() test.func(2,d=20) ``` 执行结果如下: ```bash before method func ...... in class Test func() a=1 b=10 c=2 d=20 after method func ...... ``` ### 1.3.3 装饰器有参数,被装饰类中的方法无参数 ```bash def wrapper(name="hello world"): def decorator(func): def _decorator(self): print("before method {name} ......".format(name=func.__name__)) print("name = {name}".format(name=name)) obj=func(self) print("after method {name} ......".format(name=func.__name__)) return obj return _decorator return decorator class Test(object): def __init__(self,a=1,b=10): self.a=a self.b=b @wrapper(name="Test.func") def func(self): print("in class {name} func()".format(name=Test.__name__)) print("a={a} b={b}".format(a=self.a,b=self.b)) if __name__=="__main__": test=Test() test.func() ``` 执行结果如下: ```bash before method func ...... name = Test.func in class Test func() a=1 b=10 after method func ...... ``` ### 1.2.4 装饰器有参数,被装饰类中的方法有参数 ```bash def wrapper(name="hello world"): def decorator(func): def _decorator(self,*args,**kwargs): print("before metthod {name} ......".format(name=func.__name__)) print("name = {name}".format(name=name)) obj=func(self,*args,**kwargs) print("after method {name} ......".format(name=func.__name__)) return obj return _decorator return decorator class Test(object): def __init__(self,a=1,b=10): self.a=a self.b=b @wrapper(name="Test.func") def func(self,c,d=20): print("in class {name} func()".format(name=Test.__name__)) print("a={a} b={b}".format(a=self.a,b=self.b)) print("c={c} d={d}".format(c=c,d=d)) if __name__=="__main__": test=Test() test.func(2,d=20) ``` 执行结果如下: ```bash before metthod func ...... name = Test.func in class Test func() a=1 b=10 c=2 d=20 after method func ...... ``` # 二 装饰器是类 ## 2.1 被装饰对象是函数 装饰器是类,被装饰对象是函数的时候,是通过装饰器类初始化的时候将被装饰对象函数传递给装饰器类,然后通过自动调用装饰器类中的__call__函数实现对被装饰对象的前后处理,即在这种情况下,只需要在__call__函数中编写在调用被装饰对象前后进行操作的代码即可 ### 2.1.1 装饰器无参数,被装饰对象无参数 ```bash class decorator(object): def __init__(self,func): self.func=func def __call__(self): print("before func {func}()...".format(func=self.func.__name__)) result=self.func() print("after func {func}()...".format(func=self.func.__name__)) return result @decorator def func(): print("in func func()...") if __name__=="__main__": func() ``` 执行结果如下: ```bash before func func()... in func func()... after func func()... ``` ### 2.1.2 装饰器无参数,被装饰对象有参数 ```bash class decorator(object): def __init__(self,func): self.func=func def __call__(self,*args,**kwargs): print("before func {func}()...".format(func=self.func.__name__)) result=self.func(*args,**kwargs) print("after func {func}()...".format(func=self.func.__name__)) return result @decorator def func(a,b=10): print("in func func()...") print("a= {a} b={b}".format(a=a,b=b)) if __name__=="__main__": func(2,b=20) ``` 执行结果如下: ```bash before func func()... in func func()... a= 2 b=20 after func func()... ``` ### 2.1.3 装饰器有参数,被装饰对象无参数 ```bash class decorator(object): def __init__(self,name="hello world"): self.name=name def __call__(self,func): def wrapper(): print("before func {func}()...".format(func=func.__name__)) print("name= {name}".format(name=self.name)) result=func() print("after func {func}()...".format(func=func.__name__)) return result return wrapper @decorator() def func1(): print("in func func2()...") @decorator("func2_decorator") def func2(): print("in func func2()...") @decorator(name="func3_decorator") def func3(): print("in func func3()...") if __name__=="__main__": func1() func2() func3() ``` 执行结果如下: ```bash before func func1()... name= hello world in func func2()... after func func1()... before func func2()... name= func2_decorator in func func2()... after func func2()... before func func3()... name= func3_decorator in func func3()... after func func3()... ``` ### 2.1.4 装饰器有参数,被装饰器对象有参数 ```bash class decorator(object): def __init__(self,name="hello world"): self.name=name def __call__(self,func): def wrapper(*args,**kwargs): print("before func {func}()...".format(func=func.__name__)) print("name= {name}".format(name=self.name)) result=func(*args,**kwargs) print("after func {func}()...".format(func=func.__name__)) return result return wrapper @decorator() def func1(): print("in func func2()...") @decorator("func2_decorator") def func2(a): print("in func func2()...") print("a={a}".format(a=a)) @decorator(name="func3_decorator") def func3(a,b=10): print("in func func3()...") print("a={a}, b= {b}".format(a=a,b=b)) if __name__=="__main__": func1() func2(10) func3(2,b=20) ``` 执行结果如下: ```bash before func func1()... name= hello world in func func2()... after func func1()... before func func2()... name= func2_decorator in func func2()... a=10 after func func2()... before func func3()... name= func3_decorator in func func3()... a=2, b= 20 after func func3()... ``` ## 2.2 被装饰器对象是类 同样,当被装饰对象是类是,装饰器的作用是对被装饰类的初始化方法进行功能加强,而装饰器则是以类的形式定义的 ### 2.2.1 装饰器无参数,被装饰类无参数 ```bash class decorator(object): def __init__(self,cls): self.cls=cls def __call__(self): print("before init clsss {cls}...".format(cls=self.cls.__name__)) obj=self.cls() print("after init class {cls}...".format(cls=self.cls.__name__)) return obj @decorator class Test(): def __init__(self): print("in Test class __init__ func...") def test(self): print("in Test class test func...") if __name__=="__main__": t=Test() t.test() ``` 执行结果如下: ```bash before init clsss Test... in Test class __init__ func... after init class Test... in Test class test func... ``` ### 2.2.2 装饰器无参数,被装饰类有参数 ```bash class decorator(object): def __init__(self,cls): self.cls=cls def __call__(self,*args,**kwargs): print("before init clsss {cls}...".format(cls=self.cls.__name__)) obj=self.cls(*args,**kwargs) print("after init class {cls}...".format(cls=self.cls.__name__)) return obj @decorator class Test(): def __init__(self,a,b=10): print("in Test class __init__ func...") print("a={a} b={b}".format(a=a,b=b)) def test(self): print("in Test class test func...") if __name__=="__main__": t=Test(2,b=20) t.test() ``` 执行结果如下: ```bash before init clsss Test... in Test class __init__ func... a=2 b=20 after init class Test... in Test class test func... ``` ### 2.2.3 装饰器有参数,被装饰类无参数 ```bash class decorator(object): def __init__(self,name="hello world"): self.name=name def __call__(self,cls): def wrapper(): print("before init class {cls}....".format(cls=cls.__name__)) obj=cls() print("after init class {cls}...".format(cls=cls.__name__)) return obj return wrapper @decorator(name="Test Class") class Test(): def __init__(self): print("in Test class __init__ func...") def test(self): print("in Test class test func...") if __name__=="__main__": t=Test() t.test() ``` 执行结果如下: ```bash before init class Test.... in Test class __init__ func... after init class Test... in Test class test func... ``` ### 2.2.4 装饰器有参数,被装饰类有参数 ```bash class decorator(object): def __init__(self,name="hello world"): self.name=name def __call__(self,cls): def wrapper(*args,**kwargs): print("before init class {cls}....".format(cls=cls.__name__)) obj=cls(*args,**kwargs) print("after init class {cls}...".format(cls=cls.__name__)) return obj return wrapper @decorator(name="Test Class") class Test(): def __init__(self,a,b=10): print("in Test class __init__ func...") print("a={a}, b={b}".format(a=a,b=b)) def test(self): print("in Test class test func...") if __name__=="__main__": t=Test(2,b=20) t.test() ``` 执行结果如下: ```bash before init class Test.... in Test class __init__ func... a=2, b=20 after init class Test... in Test class test func... ``` ## 2.3 被装饰对象是类中的方法 ### 2.3.1 装饰器无参数,被装饰类中的方法无参数 ```bash class decorator(object): def __init__(self,func): self.func=func def __call__(self): print("before func {func}...".format(func=self.func.__name__)) results=self.func(self) print("after func {func}...".format(func=self.func.__name__)) return results class Test(): def __init__(self): print("in Test class __init__ func...") @decorator def test(self): print("in Test class test func...") if __name__=="__main__": t=Test() t.test() ``` 执行结果如下: ```bash in Test class __init__ func... before func test... in Test class test func... after func test... ``` ### 2.3.2 装饰器无参数,被装饰类中的方法有参数 ```bash class decorator(object): def __init__(self,func): self.func=func def __call__(self,*args,**kwargs): print("before func {func}...".format(func=self.func.__name__)) results=self.func(self,*args,**kwargs) print("after func {func}...".format(func=self.func.__name__)) return results class Test(): def __init__(self): print("in Test class __init__ func...") @decorator def test(self,a,b=10): print("in Test class test func...") print("a={a} b={b}".format(a=a,b=b)) if __name__=="__main__": t=Test() t.test(2,b=20) ``` 执行结果如下: ```bash in Test class __init__ func... before func test... in Test class test func... a=2 b=20 after func test... ``` ### 2.3.3 装饰器有参数,被装饰类中的方法无参数 ```bash class decorator(object): def __init__(self,name="hello world"): self.name=name def __call__(self,func): def wrapper(self): print("before func {func}...".format(func=func.__name__)) results=func(self) print("after func {func}...".format(func=func.__name__)) return results return wrapper class Test(): def __init__(self): print("in Test class __init__ func...") @decorator(name="Test_test") def test(self): print("in Test class test func...") if __name__=="__main__": t=Test() t.test() ``` 执行结果如下: ```bash in Test class __init__ func... before func test... in Test class test func... after func test... ``` ### 2.3.4 装饰器有参数,被装饰类中的方法有参数 ```bash class decorator(object): def __init__(self,name="hello world"): self.name=name def __call__(self,func): def wrapper(self,*args,**kwargs): print("before func {func}...".format(func=func.__name__)) results=func(self,*args,**kwargs) print("after func {func}...".format(func=func.__name__)) return results return wrapper class Test(): def __init__(self): print("in Test class __init__ func...") @decorator(name="Test_test") def test(self,a,b=10): print("in Test class test func...") print("a={a}, b={b}".format(a=a,b=b)) if __name__=="__main__": t=Test() t.test(2,b=20) ``` 执行结果如下: ```bash in Test class __init__ func... before func test... in Test class test func... a=2, b=20 after func test... ```
始终坚持开源开放共享精神,同时感谢您的充电鼓励和支持!
版权所有,转载本站文章请注明出处:redrose2100, http://blog.redrose2100.com/article/140
上一篇:
Python中map,filter,reduce,zip,lambda的使用方法
下一篇:
Python中迭代器的使用方法
搜索
个人成就
出版书籍
《Pytest企业级应用实战》
测试开发技术全栈公众号
测试开发技术全栈公众号
DevOps技术交流微信群
加微信邀请进群
常用网站链接
开源软件洞察
云原生技术栈全景图
Python语言官方文档
Golang官方文档
Docker官方文档
Jenkins中文用户手册
Scrapy官方文档
VUE官方文档
Harbor官方文档
openQA官方文档
云原生开源社区
开源中国
Kubernetes中文文档
Markdown语法官方教程
Kubernetes中文社区
Kubersphere官方文档
BootStrap中文网站
JavaScript中文网
NumPy官方文档
Pandas官方文档
GitLink确实开源网站
数据库排名网站
编程语言排名网站
SEO综合查询网站
数学加减法练习自动生成网站
Kickstart Generator
文章分类
最新文章
最多阅读
特别推荐
×
Close
登录
注册
找回密码
登录邮箱:
登录密码:
图片验证码:
注册邮箱:
注册密码:
邮箱验证码:
发送邮件
注册邮箱:
新的密码:
邮箱验证码:
发送邮件