装饰器进阶

装饰器的简单回顾

装饰器
开发原则:开放封闭原则
装饰器的作用:在不改变原函数的调用方式的情况下,在函数的前后添加功能
装饰器的本质:闭包函数

装饰器的模式

def wrapper(func):
def inner(*args,**kwargs):
print("在被装饰的函数执行之前做的事")
ret =func(*args,**kwargs)
print("在被装饰的函数执行之前做的事")
return ret
return inner @wrapper #holiday = wrapper(holiday)
def holiday(day):
print("放假休息 %s 天"%day)
return '好开心' ret = holiday(3)
print(ret)

我们来看两个双下方法:__name__ 、__doc__

def wahaha():
'''
一个打印娃哈哈的函数
'''
print('娃哈哈') print(wahaha.__name__) #查看字符串格式的函数名
print(wahaha.__doc__) #document 显示函数的注释(限于多行注释)
#输出结果:
'''
wahaha 一个打印娃哈哈的函数 '''

接下来是 wraps 函数

from functools import wraps  #引用 wraps 函数

def wrapper(func):
#wraps() 加在最内层函数正上方
#@wraps(func) #在不使用 wraps 函数时 返回结果: inner inner 函数的注释
@wraps(func) #使用 wraps 函数来装饰 inner 函数 返回结果:holiday 只是一个放假通知
def inner(*args,**kwargs):
'''
inner 函数的注释
'''
print("在被装饰的函数执行之前做的事")
ret =func(*args,**kwargs)
print("在被装饰的函数执行之前做的事")
return ret
return inner @wrapper #holiday = wrapper(holiday)
def holiday(day):
'''
只是一个放假通知
'''
print("放假休息 %s 天"%day)
return '好开心' print(holiday.__name__) #当不调用 wraps 函数时,显示的为 inner 函数的名称
print(holiday.__doc__) #当不调用 wraps 函数时,显示的为 inner 函数的注释 ret = holiday(3) #在使用装饰器 wraps 函数时,并不影响 holiday 函数的使用
print(ret) #这正是装饰器函数的特点
# 返回结果:
'''
在被装饰的函数执行之前做的事
放假休息 3 天
在被装饰的函数执行之前做的事
好开心
'''

假如你有成千上万个函数使用了一个装饰器,现在你想把这些装饰器都取消掉,你要怎么做?
一个一个的取消掉? 没日没夜忙活3天。。。
过两天领导想通了,再让你加上。。。

#装饰器的三层嵌套 为的是给装饰器传入变量
import time
#flage = False #此处控制执行与否
flage = True
def timmer_out(flag):
def timmer(func):
def inner(*args,**kwargs):
if flage:
start = time.time()
ret = func(*args,**kwargs)
end = time.time()
print(end - start)
return ret
else:
ret = func(*args,**kwargs)
return ret
return inner
return timmer @timmer_out(flage) #timmer_out(flage) 表示 timmer_out(flage) == timmer
def func(): #@ 表示 @timmer 即:func == timmer(func)
time.sleep(0.1)
print("结束") @timmer_out(flage)
def func2():
time.sleep(0.1)
print("结束") func()
func2()

多个装饰器,装饰一个函数

def wrapper(func):
def inner(*args,**kwargs):
print("-----1-----")
ret = func(*args,**kwargs)
print("*****1*****")
return ret
return inner def wrapper2(func):
def inner2(*args,**kwargs):
print("-----2-----")
ret = func(*args,**kwargs)
print("*****2*****")
return ret
return inner2 def wrapper3(func):
def inner3(*args,**kwargs):
print("-----3-----")
ret = func(*args,**kwargs)
print("*****3*****")
return ret
return inner3 @wrapper3
@wrapper2
@wrapper
def f():
print("in f")
return '就是这样'
print(f())
输出结果如下:
-----3-----
-----2-----
-----1-----
in f
*****1*****
*****2*****
*****3*****
就是这样

执行过成可参考下图

Python类中的装饰器在当前类中的声明与调用

class Test():
xx = False def __init__(self):
pass def test(func):
def wrapper(self, *args, **kwargs):
# print(self.xx)
return func(self, *args, **kwargs) return wrapper @test
def test_a(self, a, b):
print(f'ok,{a} {b}') # ok,12 13 t = Test()
t.test_a(12, 13)

注意:

1. 其中装饰器test是在类Test中声明并在其方法test_a中调用

2. 装饰器test内层wrapper函数的首参数是self

参考资料:

1. Python decorators in classes

day 12 - 1 装饰器进阶的更多相关文章

  1. day4之装饰器进阶、生成器迭代器

    装饰器进阶 带参数的装饰器 # 某一种情况# 500个函数加装饰器, 加完后不想再加这个装饰器, 再过一个季度,又想加上去# 你可以设计你的装饰器,来确认是否执行 # 第一种情况 # 想要500个函数 ...

  2. Python函数--装饰器进阶

    开放封闭原则 1.对扩展是开放的 为什么要对扩展开放呢? 我们说,任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改.所以我们必须允许代码扩展.添加新功能. 2.对修改是封 ...

  3. Python装饰器进阶

    装饰器进阶 现在,我们已经明白了装饰器的原理.接下来,我们还有很多事情需要搞清楚.比如:装饰带参数的函数.多个装饰器同时装饰一个函数.带参数的装饰器和类装饰器. 装饰带参数函数 def foo(fun ...

  4. (转)python装饰器进阶一

    Python装饰器进阶之一 先看例子 网上有很多装饰器的文章,上来说半天也没让人看明白装饰器到底是个什么,究竟有什么用,我们直接来看几个例子. Python递归求斐波那契数列 def fibonacc ...

  5. python 基础篇 12 装饰器进阶

    本节主要内容:1. 通⽤装饰器回顾2. 函数的有⽤信息3. 带参数的装饰器4. 多个装饰器同时装饰⼀个函数 ⼀. 通⽤装饰器的回顾开闭原则: 对增加功能开放. 对修改代码封闭装饰器的作⽤: 在不改变原 ...

  6. Python学习之装饰器进阶

    函数知识回顾: 函数的参数分为:实参和形参. 实参:调用函数的时候传入的参数: 形参:分为3种(位置参数.默认参数.动态传参) 位置参数:必须传值 def aaa(a,b): print(a,b) a ...

  7. 从入门到自闭之python三大器--装饰器进阶

    装饰器的进阶 有参装饰器: # def warpper(func): # def inner(*args,**kwargs): # user = input("user:") # ...

  8. CSIC_716_20191113【装饰器进阶以及迭代器】

    装饰器的进阶主要包含叠加装饰器和有参装饰器 叠加装饰器:在一个被装饰的对象中,添加多个装饰器. 为什么要用叠加装饰器的原因:    -每一个新的功能都应该写一个新的装饰器,否则会导致,代码冗余,结构不 ...

  9. Java设计模式12:装饰器模式

    装饰器模式 装饰器模式又称为包装(Wrapper)模式.装饰器模式以多客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 装饰器模式的结构 通常给对象添加功能,要么直接修改对象添加相应的功能, ...

随机推荐

  1. Django(五)框架之模板继承和静态文件配置

    https://www.cnblogs.com/haiyan123/p/7731959.html 一.模板继承 目的是:减少代码的冗余 语法: {% block classinfo %} {% end ...

  2. python之路入门篇

    一. Python介绍 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,Guido开始写能够解释Python语言语法的解释器.Python这个名字,来 ...

  3. MySQL信息提示不是英文问题

    安装好MySQL后,运行SQL的提示信息总不是英文mysql> select database; ERROR 1064 (42000): 安装好MySQL后,运行SQL的提示信息总不是英文 my ...

  4. 异常处理和Throwable中的几个方法

    package cn.lijun.demo; /* * try { //需要被检测的语句. } catch(异常类 变量) { //参数. //异常的处理语句. } finally { //一定会被执 ...

  5. eslint相关工具

    eslint工具 1. vscode搜索eslint安装,就可以在写代码时报eslint的错误了 2.文件 --> 首选项 --> 设置 --> 选ESLint --> 勾选A ...

  6. 信用评分卡 (part 1 of 7)

    python信用评分卡(附代码,博主录制) https://study.163.com/course/introduction.htm?courseId=1005214003&utm_camp ...

  7. Ansible Callback

    非api模式下自定义callback ansible.cfg中开启callback功能 callback_plugins = /usr/share/ansible/plugins/callback # ...

  8. 《Apache Kafka实战》读书笔记-调优Kafka集群

    <Apache Kafka实战>读书笔记-调优Kafka集群 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.确定调优目标 1>.常见的非功能性要求 一.性能( ...

  9. 【C#】C#创建自定义Object对象

    艹,老是忘!!! }; 记录一下,var obj = new { Name="lily",Age=12};

  10. spring+springmvc+ibatis整合注解方式实例【转】

    源自-----> http://shaohan126448.iteye.com/blog/2033563 (1)web.xml文件(Tomcat使用) 服务器根据配置内容初始化spring框架, ...