装饰器就是一个闭包,它的主要作用是在不改变原函数的基础上对原函数功能进行扩展。

我们先来写一个简单的函数:

from time import sleep

def foo():
print("Hello World!")
sleep(2)

现在我们要对这个函数加一些功能,比如说打印这个函数的执行时间

有人说,这还不简单啊,直接修改foo函数呢,确实,这是最简单的一种方法。但是在我们实际工作中,有时候是不能对调用的函数进行修改的,那该怎么办呢?

我们可以重新写个打印时间的函数去调用foo函数啊,比如:

import time
from time import sleep def foo():
print("Hello World!")
sleep(2) def show_time(func):
start_time = time.time()
func()
end_time = time.time()
print(end_time - start_time)

调用:

show_time(foo)

# 输出:
Hello World!
2.0000178813934326

很好,确实是在不修改foo函数的基础上实现了需求,但是。。。。。有个大问题,改变了函数的调用方式,前面是调用foo()的,现在需要修改成调用show_time()。

看来这种方法也不行。

这个时候就是闭包大展身手的机会了

import time
from time import sleep def foo():
print("Hello World!")
sleep(2) def show_time(func):
def inner():
start_time = time.time()
func()
end_time = time.time()
print(end_time - start_time)
return inner # 调用
foo = show_time(foo)
foo() # 输出
Hello World!
2.000027656555176

到这里已经完美地实现了我们的需求,这就是装饰器。装饰器有个高大上的写法,就是装饰器符号@

上面的代码我们修改成用装饰器符号@来写:

import time
from time import sleep def show_time(func):
def inner():
start_time = time.time()
func()
end_time = time.time()
print(end_time - start_time)
return inner @show_time # 其实就相当于foo = show_time(foo)
def foo():
print("Hello World!")
sleep(2) # 调用
foo()

@show_time的作用就是执行foo()时,跳转到去执行inner(),如下图:

被装饰函数的参数

如果被装饰的函数有形参,那么在装饰器函数中该怎么写呢?

import time
from time import sleep def show_time(func):
def inner(*x):
start_time = time.time()
func(*x)
end_time = time.time()
print(end_time - start_time)
return inner @show_time
def add(*args):
sum = 0
for arg in args:
sum += arg
print(sum)
sleep(2) add(3, 5)

装饰器函数参数

有些时候我们可能需要对不同的被装饰函数加些不同的功能,比如需要对某些函数加上日志打印,那该怎么做呢?

import time
from time import sleep def logger(flag="false"):
def show_time(func):
def inner(*x):
start_time = time.time()
func(*x)
end_time = time.time()
print(end_time - start_time)
if flag == "true":
print("打印日志记录")
return inner
return show_time @logger("true") # 打印日志记录
def add(*args):
sum = 0
for arg in args:
sum += arg
print(sum)
sleep(2) @logger() # 不需要打印日志记录
def foo():
print("Hello World!")
sleep(2)

Python3学习笔记(十三):装饰器的更多相关文章

  1. Python学习笔记:装饰器

    Python 装饰器的基本概念和应用 代码编写要遵循开放封闭原则,虽然在这个原则是用的面向对象开发,但是也适用于函数式编程,简单来说,它规定已经实现的功能代码不允许被修改,但可以被扩展,即: 封闭:已 ...

  2. Python学习笔记012——装饰器

    1 装饰器 1.1装饰器定义 在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator). 1.2 装饰器分类 装饰器:函数装饰器,类装饰器,函数的装饰器,类的装饰器 装饰器:函数装饰函 ...

  3. python学习笔记之装饰器、递归、算法(第四天)

    参考老师的博客: 金角:http://www.cnblogs.com/alex3714/articles/5161349.html 银角:http://www.cnblogs.com/wupeiqi/ ...

  4. python学习笔记:装饰器2

    python的装饰器本质是函数,为了不改变装饰目标函数内部代码而增加额外功能而存在 一.一般装饰函数实例: import datetime def func_name(func):#定义一个装饰函数, ...

  5. Python学习笔记之装饰器原理

    def decorator(fn): def wrapper(): print("询价") fn() print("购买成功!") return wrapper ...

  6. python学习笔记(五):装饰器、生成器、内置函数、json

    一.装饰器 装饰器,这个器就是函数的意思,连起来,就是装饰函数,装饰器本身也是一个函数,它的作用是用来给其他函数添加新功能,比如说,我以前写了很多代码,系统已经上线了,但是性能比较不好,现在想把程序里 ...

  7. python学习笔记之装饰器、生成器、内置函数、json(五)

    一.装饰器 装饰器,这个器就是函数的意思,连起来,就是装饰函数,装饰器本身也是一个函数,它的作用是用来给其他函数添加新功能比如说,我以前写了很多代码,系统已经上线了,但是性能比较不好,现在想把程序里面 ...

  8. Python3学习笔记十三

    1.   css 老师的博客:http://www.cnblogs.com/yuanchenqi/articles/6856399.html 选择器:找到想要改变的标签 css的功能:渲染和布局 2. ...

  9. Python3学习笔记15-迭代器与生成器

    生成器 如果创建一个有很多元素的列表,但是只需要访问前几个元素,后面的元素占着的空间就白白浪费了 在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间. 在Pytho ...

  10. python3.4学习笔记(十三) 网络爬虫实例代码,使用pyspider抓取多牛投资吧里面的文章信息,抓取政府网新闻内容

    python3.4学习笔记(十三) 网络爬虫实例代码,使用pyspider抓取多牛投资吧里面的文章信息PySpider:一个国人编写的强大的网络爬虫系统并带有强大的WebUI,采用Python语言编写 ...

随机推荐

  1. SpringBoot-2-基本配置

    自定义启动配置 在resources下面新建一个banner.txt文件,里面写入自己想要的内容 /////////////////////////////////////////////////// ...

  2. jQuery可拖拽旋转的3D图片墙

    在线演示 本地下载

  3. node工具之http-proxy-middleware

    简介 一个轻松的配置代理服务器的中间件,让Node.js代理变得简单 url路径 foo://example.com:8042/over/there?name=ferret#nose \_/ \___ ...

  4. [Next] 服务端渲染知识补充

    渲染 渲染:就是将数据和模版组装成 html 客户端渲染 客户端渲染模式下,服务端把渲染的静态文件给到客户端,客户端拿到服务端发送过来的文件自己跑一遍 js,根据 JS 运行结果,生成相应 DOM,然 ...

  5. SQL学习(三)之子句和函数

    函数 COUNT()/计数.MIN()/最小值.MAX()/最大值.AVG()/平均值.SUM()/和 子句 子句是语句的一部分包括WHERE.GROUP.ORDER.LIMIT WHERE:条件 G ...

  6. k8s自签TLS证书

    自签TLS证书 TLS证书用于进行通信使用,k8s组件需要的证书有: 第一步:安装证书生成工具cfssl 在这之前需要先建立一个目录来存放安装的工具mkdir ssl,后面将安装的工具移动到各自的目录 ...

  7. UI测试

    先是从一张图开始,让大家看看这个图里有什么不妥: 接着告诉大家具体有哪些不妥: 然后结合这个找茬的过程分享下界面测试的概念和方法. 界面测试:简称UI测试,测试功能模块界面上看到的所有元素(包括空文字 ...

  8. vue 组件基本使用

    组件的基本使用 注册组件 注册组件就是利用Vue.component()方法,先传入一个自定义组件的名字,然后传入这个组件的配置.vue.component()注册的全局组件 Vue.componen ...

  9. jquery 滚动事件-记录自己常用的

    1.h5端页面滑动至第3屏及以后才出现置顶按钮 $(document).scroll(function() { var scroH = $(document).scrollTop(); //滚动高度 ...

  10. eclipses配置tomcat

    1,项目右键属性,设置为1.8,与jdk相对应 2,自动发布,tomcat 3,使用自己的tomcat 4,