python装饰器函数

1.装饰器函数引导

功能:计算函数执行时长

import time

"""
方式一:
函数首位添加时间,差值就是函数执行时间
缺点:每个函数都要加上,工作量大
"""
def f1():
start_time = time.time()
print("f1 excute")
end_time = time.time()
print(end_time-start_time) f1()
import time

"""
方式二:
调用函数前后
缺点:调用函数前后都要加,别人引用的也要加
""" def f1():
print("f1 excute") start_time = time.time()
f1()
end_time = time.time()
print(end_time - start_time)
import time

"""
方式三:
写个计算函数执行时间函数
缺点:改变了函数的调用方式
""" def f1():
print("f1 excute") def timer(func):
start_time = time.time()
func
end_time = time.time()
print(end_time - start_time) timer(f1())

想要不改变调用方式的前提下完成该功能

import time

"""
方式四:
缺点:还要复制操作
""" def f1():
print("f1 excute") def timer(func):
def inner():
start_time = time.time()
func
end_time = time.time()
print(end_time - start_time)
return inner f1 = timer(f1())
f1()

直接将赋值操作替换

import time

def timer(func):
def inner():
start_time = time.time()
func()
end_time = time.time()
print(end_time - start_time) return inner @timer
def f1():
print("f1 excute") f1()
总结:
装饰器的本质:一个闭包函数
装饰器的功能:在不修改原函数及其调用方式的情况下对原函数功能进行扩展
#带参数
import time
def timer(func):
def inner(a):
start = time.time()
func(a)
print(time.time() - start)
return inner @timer
def f1(a):
print(a) f1()
# 带返回值
import time
def timer(func):
def inner(*args,**kwargs):
start = time.time()
re = func(*args,**kwargs)
print(time.time() - start)
return re
return inner @timer #==> func1 = timer(func1)
def func1(a,b):
print('in func1') @timer #==> func2 = timer(func2)
def func2(a):
print('in func2 and get a:%s'%(a))
return 'fun2 over' func1('aaaaaa','bbbbbb')
print(func2('aaaaaa'))
import time

def timer(func):
def inner(*args, **kwargs):
start = time.time()
re = func(*args, **kwargs)
print(time.time() - start)
return re return inner @timer # ==> func1 = timer(func1)
def f1(a, b):
print('f1 excute ,a=%s,b=%s' % (a, b)) @timer # ==> func2 = timer(func2)
def f2(a):
print(a)
return 'f2 over' f1('x1', 'x2')
a = f2('a')
print(a)
# f1 excute ,a=x1,b=x2
# 0.0
# a
# 0.0
# f2 over
import time
# from functools import wraps def timer(func):
# @wraps(func) # 防止查看函数注释失效
def inner(*args, **kwargs):
start = time.time()
re = func(*args, **kwargs)
print(time.time() - start)
return re return inner @timer # ==> func1 = timer(func1)
def f1(a, b):
"""f1函数注释"""
print('f1 excute ,a=%s,b=%s' % (a, b)) @timer # ==> func2 = timer(func2)
def f2(a):
"""f2函数注释"""
print(a)
return 'f2 over' print(f1.__doc__) # 查看函数注释 None
print(f1.__name__) # 查看函数名称 inner

正常情况:

def demo():
"""函数注释"""
print("a") print(demo.__doc__) # 查看函数注释 函数注释
print(demo.__name__) # 查看函数名称 demo

为防止失效:

import time
from functools import wraps def timer(func):
@wraps(func) # 防止查看函数注释失效
def inner(*args, **kwargs):
start = time.time()
re = func(*args, **kwargs)
print(time.time() - start)
return re return inner @timer # ==> func1 = timer(func1)
def f1(a, b):
"""f1函数注释"""
print('f1 excute ,a=%s,b=%s' % (a, b)) @timer # ==> func2 = timer(func2)
def f2(a):
"""f2函数注释"""
print(a)
return 'f2 over' print(f1.__doc__) # 查看函数注释 f1函数注释
print(f1.__name__) # 查看函数名称 f1

2.开放封闭原则

1.对扩展是开放的
我们说,任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改。所以我们必须允许代码扩展、添加新功能。 2.对修改是封闭的
就像我们刚刚提到的,因为我们写的一个函数,很有可能已经交付给其他人使用了,如果这个时候我们对其进行了修改,很有可能影响其他已经在使用该函数的用户。 装饰器完美的遵循了这个开放封闭原则

3.装饰器的主要功能和装饰器的固定结构

装饰器的主要功能:在不修改原函数的调用方式的基础上,在函数前后添加功能,实现功能扩展

from functools import wraps

def demo(func):
@wraps(func) # 防止查看函数注释等方法失效
def inner(*args, **kwargs):
"""调用函数前要实现的功能"""
re = func(*args, **kwargs)
"""调用函数后要实现的功能"""
return re return inner

4.带参数的装饰器

使用参数控制装饰器的使用与否:在后面再嵌套一层

from functools import wraps

def outer(flag):
def demo(func):
@wraps(func)
def inner(*args, **kwargs):
if flag: print("函数调用前")
re = func(*args, **kwargs)
if flag: print("函数调用后")
return re return inner return demo @outer(False)
def f1():
print("f1 execute") f1()

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

from functools import wraps

def timer1(func):
@wraps(func)
def inner(*args, **kwargs):
print('''timer1执行函数之前要做的''')
re = func(*args, **kwargs)
print('''timer1执行函数之后要做的''')
return re return inner def timer2(func):
@wraps(func)
def inner(*args, **kwargs):
print('''timer2执行函数之前要做的''')
re = func(*args, **kwargs)
print('''timer2执行函数之后要做的''')
return re return inner @timer1
@timer2
def func():
print(111) func()
# timer1执行函数之前要做的
# timer2执行函数之前要做的
#
# timer2执行函数之后要做的
# timer1执行函数之后要做的

python基础篇_004_装饰器函数的更多相关文章

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

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

  2. 【笔记】Python基础五:装饰器

    一,什么是装饰器 本质就是函数,功能是为其他函数添加附加功能 原则: 1,不修改被修饰函数的源代码 2,不修改被修饰函数的调用方式 例子: import time def timmer(func): ...

  3. python基础-内置装饰器classmethod和staticmethod

    面向对象编程之classmethod和staticmethod classmethod 和 staticmethod都是python内置的装饰器 classmethod 的作用:给在类内部定义的方法装 ...

  4. Python学习日记(九) 装饰器函数

    1.import time a.time.time() 获取到当前的时间,返回值为浮点型 import time print(time.time()) #1565422783.6497557 b.ti ...

  5. python基础--闭包and装饰器

    闭包函数:函数内部定义的函数:引用了外部变量但非全局变量 装饰器:有了闭包的概念再去理解装饰器就会相对容易一些.python装饰器本质上就是一个函数,它可以让其他函数在不需要做任何代码变动的前提下增加 ...

  6. Python基础:13装饰器

    装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的应用有插入日志.性能测试.事务处理等.装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同 ...

  7. python基础8(装饰器)

    1.装饰器本质 装饰器的本质:一个闭包函数 装饰器的功能:在不修改原函数及其调用方式的情况下对原函数功能进行扩展 2.装饰器函数 假设要写一个输出函数执行时间的装饰器 def timer(func): ...

  8. python基础十之装饰器

    1,装饰器的形成 编程原则:开放封闭原则. 开放:对扩展是开放的 封闭:对修改是封闭的 因为修改是封闭的,所以为了对函数进行功能的扩展,就使用装饰器! 2,装饰器的定义 # wrapper就是一个装饰 ...

  9. python基础5之装饰器

    内容概要: 一.装饰器前期知识储备 1.python解释函数代码过程: python解释器从上往下顺序解释代码,碰到函数的定义代码块不会立即执行它,而是将其放在内存中,等到该函数被调用时,才执行其内部 ...

随机推荐

  1. LOJ2340 [WC2018] 州区划分 【FMT】【欧拉回路】

    题目分析: 这题是WC的题??? 令 $g[S] = (\sum_{x \in S}w_x)^p$ $h[S] = g[S]$如果$S$不是欧拉回路 $d[S] = \frac{f[S]}{g[All ...

  2. 【LOJ565】【LibreOJ Round #10】mathematican 的二进制 DP 分治FFT

    题目大意 有一个无限长的二进制串,初始时它的每一位都为 \(0\).现在有 \(m\) 个操作,其中第 \(i\) 个操作是将这个二进制串的数值加上 \(2^{a_i}\).我们称每次操作的代价是这次 ...

  3. rt-thread 之网络组件

    @2019-02-23 [小记] 文件 <net_sockets.c> 为兼容标准 BSD Socket API 文件 <sal_socket.c> 为网络中间抽象层 文件 & ...

  4. 常用js方法整理(个人)

    开头总要有点废话 今天想了下,还是分享下自己平时积累的一些实用性较高的js方法,供大家指点和评价.本想分篇介绍,发现有点画蛇添足.整理了下也没多少拿得出手的方法,自然有一些是网上看到的个人觉得很有实用 ...

  5. Day049--jQuery的文档操作和事件介绍

    今日内容 DOM操作(CRUD) js中DOM document.createElement('p') appendChild() insertBefore() removeChild() 创建元素 ...

  6. 20175209 《Java程序设计》第二周学习总结

    教材学习内容总结 二三章介绍的主要是Java中的基本知识:数据类型及转换,数据的输入输出,数组,运算符表达式,和常见的一些语句,这些都是帮助我们学习Java的基本知识,而这些知识很大一部分都和C语言相 ...

  7. kafka 基础知识梳理及集群环境部署记录

    一.kafka基础介绍 Kafka是最初由Linkedin公司开发,是一个分布式.支持分区的(partition).多副本的(replica),基于zookeeper协调的分布式消息系统,它的最大的特 ...

  8. Python的设计模式

    设计模式是什么? 设计模式是经过总结.优化的,对我们经常会碰到的一些编程问题的可重用解决方案.一个设计模式并不像一个类或一个库那样能够直接作用于我们的代码.反之,设计模式更为高级,它是一种必须在特定情 ...

  9. 基于USB网卡适配器劫持DHCP Server嗅探Windows NTLM Hash密码

    catalogue . DHCP.WPAD工作过程 . python Responder . USB host/client adapter(USB Armory): 包含DHCP Server . ...

  10. 四十四、Linux 线程——线程同步之死锁以及线程和信号

    44.1 死锁 死锁: 两个线程试图同时占有两个资源,并按不同的次序锁定相应的共享资源 解决方式: 按相同的次序锁定相应的共享资源 使用函数 pthread_mutex_trylock(),它是函数 ...