装饰器是对已有的模块进行装饰(添加新功能)的函数。

现有一段代码:

 import time
def func1():
time.sleep(3)
print("in the func1")
def func2():
time.sleep(2)
print("in the func2")
func1()
func2()

现在需要增加func1和func2的功能,计算段代码的运行时间。

思路1:修改函数内的代码:

 import time
def func1():
start_time = time.time()
time.sleep(3)
print("in the func1")
stop_time = time.time()
print("this program run %ss"%(stop_time-start_time))
def func2():
start_time = time.time()
time.sleep(2)
print("in the func2")
stop_time = time.time()
print("this program run %ss"%(stop_time-start_time))
func1()
func2()

每个函数都添加了红色的代码段,如果需要改的func较多时,该方法明显不适用。并且违反了为函数添加附加功能时的原则1:不能修改被装饰函数的源代码。

思路2:增加新函数:

 import time
def func1():
time.sleep(3)
print("in the func1")
def func2():
time.sleep(2)
print("in the func2")
def func_new1():
start_time = time.time()
func1()
stop_time =time.time()
print("this program run %ss"%(stop_time-start_time))
def func_new2():
start_time = time.time()
func2()
stop_time =time.time()
print("this program run %ss"%(stop_time-start_time))
func_new1()
func_new2()

该方法增加了新函数,将原有函数引用至新函数中。但问题又来了,需要改主程序中对原有函数的引用方法,违反了并且违反了为函数添加附加功能时的原则2:不能修改被装饰函数的调用方式。

此刻,我们需要新的知识储备来完善对装饰器的理解

1.函数的嵌套

2.高阶函数

3.函数——变量的关系

高阶函数+嵌套函数===》装饰器

插入名词的解释!!

高阶函数:满足下列原则之一的就是高阶函数:

  a.把一个函数名当作实参传给另一个函数的函数。

 import time
def bar():
time.sleep(3)
print("in the bar")
def test(func):
start_time = time.time()
func()
stop_time = time.time()
print("the func run time is %s"%(stop_time-start_time))
test(bar)

在此函数中,bar作为实参被传递给形参func,test(bar)。通过test()函数为bar()增加了新功能,且没有改变bar()的源代码。但改变了原有bar()的调用方式。

实现了不修改被装饰函数的源代码情况下为其添加新功能的目的。

  b.返回值中包含函数名

 import time
def bar():
time.sleep(3)
print("in the bar")
def test(func):
print(func)
print()
return func
bar = test(bar)
bar()

在此代码中,原有函数bar(),然后bar作为函数名被传给新增函数test(),随后又作为该函数的返回值。相当与给bar()增加了新的功能(显示bar()的内存地址),但没有改变bar()的调用方式。

嵌套函数:在函数体内声明的函数(必须是声明,不能是调用)

def test1():
print("in the test1")
def test2():
print("in the test2")
test2()
test1()

test2()是在test1()中声明的函数

将高阶函数与嵌套函数结合,

 import time
def timmer(func):
def deco():
start_time = time.time()
func()
stop_time = time.time()
print("the func run time is %ss"%(stop_time-start_time))
return deco
@timmer    #等于在func1被调用前加上func1=timmer(func1)
def func1():
time.sleep(3)
print("in the func1")
@timmer
def func2():
time.sleep(2)
print("in the func2")
func1()
func2()

其中@timmer = func1= timmer(func1),就是在被装饰的函数前加上装饰器的名称。在没有改变被装饰代码的源代码及调用方式的情况下增加了其功能。

python中装饰器使用的更多相关文章

  1. 8.Python中装饰器是什么?

    Python中装饰器是什么? A Python decorator is a specific change that we make in Python syntax to alter functi ...

  2. python中装饰器的原理以及实现,

    python版本 3.6 1.python的装饰器说白了就是闭包函数的一种应用场景,在运用的时候我们遵循 #开放封闭原则:对修改封闭,对拓展开放 2.什么是装饰器 #装饰他人的器具,本身可以是任意可调 ...

  3. python中装饰器修复技术

    python装饰器@wraps作用-修复被装饰后的函数名等属性的改变 Python装饰器(decorator)在实现的时候,被装饰后的函数其实已经是另外一个函数了(函数名等函数属性会发生改变), 为了 ...

  4. python中装饰器的执行细节

    本文代码借用 廖雪峰的python教程(官网:http://www.liaoxuefeng.com/) 不了解装饰器的可以先看教程 直接上带参数装饰器的代码 def log(text): def de ...

  5. Python中装饰器(转)

    本文由 伯乐在线 - 7even 翻译,艾凌风 校稿.未经许可,禁止转载!英文出处:Simeon Franklin.欢迎加入翻译组. 好吧,我标题党了.作为 Python 教师,我发现理解装饰器是学生 ...

  6. python中装饰器(语法糖)概念

    “”“” 什么是装饰器? """ 还是通过一个例子来慢慢说明 先看下面的例子 def func_1(x): return x*2 def fun_2(x): return ...

  7. Python核心技术与实战——十四|Python中装饰器的使用

    我在以前的帖子里讲了装饰器的用法,这里我们来具体讲一讲Python中的装饰器,这里,我们从前面讲的函数,闭包为切入点,引出装饰器的概念.表达和基本使用方法.其次,我们结合一些实际工程中的例子,以便能再 ...

  8. Python中装饰器的用法

    定义: 装饰器本身就是一个函数 为其他函数提供附加功能 不改变源代码 不改变原调用方式 装饰器=高阶函数+嵌套函数 知识点: 函数本身就是一个变量(意味着可以被复制给一个变量:test=test(1) ...

  9. python中装饰器的原理

    装饰器这玩意挺有用,当时感觉各种绕,现在终于绕明白了,俺滴个大爷,还是要慢慢思考才能买明白各种的真谛,没事就来绕一绕 def outer(func): def inner(): print(" ...

随机推荐

  1. python+爬虫+签名

    在公众号,看到一个比较好玩的程序.它使用post的来传送请求,以前没有遇到过.可能是自己,写的程序太少了.查了一下post的用法: 通常,你想要发送一些编码为表单形式的数据——非常像一个 HTML 表 ...

  2. 径向模糊(Radial Blur)

    [径向模糊(Radial Blur)] 径向模糊,是一种从中心向外呈幅射状的逐渐模糊的效果,在图形处理软件photoshop里面也有这个模糊滤镜.而在游戏中常常用来模拟一些动感的效果,如鬼泣4中的场景 ...

  3. Idea单元测试Junit Generator设置

    0. setting--->plugins--->brose repostories-->输入JUnitGenerator V2.0 1.junit generator自动生成测试代 ...

  4. 超详细 Nginx 极简教程

    什么是Nginx? Nginx (engine x) 是一款轻量级的Web 服务器 .反向代理服务器及电子邮件(IMAP/POP3)代理服务器. 什么是反向代理? 反向代理(Reverse Proxy ...

  5. Centos 7 MariaDB Galera cluster 部署

    一.安装环境准备 1.系统: CentOS Linux release 7.4.1708 (Core) 2.hosts 10.6.32.51 openstack1 10.6.32.52 opensta ...

  6. LightOJ - 1027 Dangerous Maze 期望

    你在迷宫中;开始时在你面前看到n扇门.你可以选择你喜欢的任何门.所有门的选择门的概率是相等的. 如果您选择第i个门,它可以让您回到您在xi(xi小于0)分钟内开始的相同位置,也可以在xi(xi大于0) ...

  7. VM虚拟机 安装linux系统

    首先需要下载VMware10 和CentOS-6.4,我这边提供了百度网盘,可供下载链接:https://pan.baidu.com/s/1vrJUK167xnB2JInLH890fw 密码:r4jj ...

  8. CyclicBarrier簡介

    package CyclicBarrier; import java.util.concurrent.CyclicBarrier;import java.util.concurrent.atomic. ...

  9. WAV与PCM

    转: 1.PCM格式介绍: PCM(Pulse Code Modulation)也被称为 脉码编码调制.PCM中的声音数据没有被压缩,如果是单声道的文件,采样数据按时间的先后顺序依次存入.(它的基本组 ...

  10. 【校招面试 之 C/C++】第33题 C++ 11新特性(四)之STL容器

    C++ 11新增array.forward_list(单链表).unordered_set.unordered_map集中容器.