装饰器进阶

装饰器的简单回顾

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

装饰器的模式

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. react-native中使用长列表

    React Native 提供了几个适用于展示长列表数据的组件,一般而言我们会选用FlatList或是SectionList. FlatList组件用于显示一个垂直的滚动列表,其中的元素之间结构近似而 ...

  2. cnblogs latex公式

    选项->启用数学公式支持 \begin{equation*} \begin{split} &xxx\\ &xxx\\ \end{split} \end{equation*} (\ ...

  3. 如何计算Java对象所占内存的大小

    [ 简单总结: 随便一个java项目,引入jar包: lucene-core-4.0.0.jar 如果是 maven项目,直接用如下依赖: <dependency> <groupId ...

  4. io系列之常用流一

    一. 读取键盘录入和数据打印 在System类中, System.out: 对应的是标准输出设备(控制台)(一个PrintStream). System.in: 对应的是标准输入设备(键盘)(一个In ...

  5. TestNg 10. 多线程测试-xml文件实现

    代码如下: package com.course.testng.multiThread; import org.testng.annotations.Test; public class MultiT ...

  6. 2018 icpc-ecfinal后记

    打完这场终于可以回校0基础预习一个学期的课程了.    安详.jpg 可惜了,差了点罚时没有拿银,不过有了徐州差一分钟银牌的经历之后,已经没有什么能让我遗憾了. 仿佛又打了一场半年前的西安邀请赛,区别 ...

  7. ADB interface驱动

    原文地址:https://blog.csdn.net/weixin_42108952/article/details/80153402

  8. 2017-12-14python全栈9期第一天第四节之python分类

    python的环境. 编译型:一次性将所有程序编译成二进制文件. 缺点:开发效率低,不能跨平台. 优点:运行速度快. :C,C++等等. 解释型:当程序执行时,一行一行的解释. 优点:开发效率高,可以 ...

  9. 面向对象【林老师版】:面向过程vs面向对象(一)

    一.面向过程 1.引子 面向过程:核心是过程二字,过程指的是解决问题的步骤,设计一条流水线,机械式的思维方式优点:复杂的问题流程化,进而简单化缺点:可扩展性差 2.验证代码 import json i ...

  10. 【英文文档】 Installing Go from source Go语言官方编译指南 2019.02.27

    Introduction Go is an open source project, distributed under a BSD-style license. This document expl ...