Python3学习笔记(十三):装饰器
装饰器就是一个闭包,它的主要作用是在不改变原函数的基础上对原函数功能进行扩展。
我们先来写一个简单的函数:
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学习笔记(十三):装饰器的更多相关文章
- Python学习笔记:装饰器
Python 装饰器的基本概念和应用 代码编写要遵循开放封闭原则,虽然在这个原则是用的面向对象开发,但是也适用于函数式编程,简单来说,它规定已经实现的功能代码不允许被修改,但可以被扩展,即: 封闭:已 ...
- Python学习笔记012——装饰器
1 装饰器 1.1装饰器定义 在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator). 1.2 装饰器分类 装饰器:函数装饰器,类装饰器,函数的装饰器,类的装饰器 装饰器:函数装饰函 ...
- python学习笔记之装饰器、递归、算法(第四天)
参考老师的博客: 金角:http://www.cnblogs.com/alex3714/articles/5161349.html 银角:http://www.cnblogs.com/wupeiqi/ ...
- python学习笔记:装饰器2
python的装饰器本质是函数,为了不改变装饰目标函数内部代码而增加额外功能而存在 一.一般装饰函数实例: import datetime def func_name(func):#定义一个装饰函数, ...
- Python学习笔记之装饰器原理
def decorator(fn): def wrapper(): print("询价") fn() print("购买成功!") return wrapper ...
- python学习笔记(五):装饰器、生成器、内置函数、json
一.装饰器 装饰器,这个器就是函数的意思,连起来,就是装饰函数,装饰器本身也是一个函数,它的作用是用来给其他函数添加新功能,比如说,我以前写了很多代码,系统已经上线了,但是性能比较不好,现在想把程序里 ...
- python学习笔记之装饰器、生成器、内置函数、json(五)
一.装饰器 装饰器,这个器就是函数的意思,连起来,就是装饰函数,装饰器本身也是一个函数,它的作用是用来给其他函数添加新功能比如说,我以前写了很多代码,系统已经上线了,但是性能比较不好,现在想把程序里面 ...
- Python3学习笔记十三
1. css 老师的博客:http://www.cnblogs.com/yuanchenqi/articles/6856399.html 选择器:找到想要改变的标签 css的功能:渲染和布局 2. ...
- Python3学习笔记15-迭代器与生成器
生成器 如果创建一个有很多元素的列表,但是只需要访问前几个元素,后面的元素占着的空间就白白浪费了 在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间. 在Pytho ...
- python3.4学习笔记(十三) 网络爬虫实例代码,使用pyspider抓取多牛投资吧里面的文章信息,抓取政府网新闻内容
python3.4学习笔记(十三) 网络爬虫实例代码,使用pyspider抓取多牛投资吧里面的文章信息PySpider:一个国人编写的强大的网络爬虫系统并带有强大的WebUI,采用Python语言编写 ...
随机推荐
- TCP 三次握手和四次挥手
TCP 三次握手和四次挥手 作为面试会被经常考察的的点,自己复习了一下,总结如下: TCP 三次握手 先上图: 所谓三次握手,是指建立一个 TCP 连接时,需要客户端和服务器总共发送 3 个包. 第一 ...
- 第二章 单表查询 T-SQL语言基础(1)
单表查询(1) 本章:逻辑查询处理,特定的SELECT查询生成正确的结果集而要经历的一系列逻辑阶段;单表查询的其他方面,包括:运算符,空值(NULL),字符的处理和临时数据,分级(ranking),C ...
- JS基础_标识符
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- Vue使用Elementui修改默认最快方法!
相信大家都需要过,在Vue中使用Elementui的时候,遇到最多也最蛋疼的问题就是修改默认样式,接下来直奔主题: // template <el-progress :text-inside=& ...
- PostgreSQL 按照日期范围查询
method 1 select * from user_info where create_date >= '2019-05-01' and create_date < '2019-08- ...
- cgicc使用
CgiCc 使用 一.下载 下载地址: http://ftp.gnu.org/gnu/cgicc/ ftp://ftp.gnu.org/gnu/cgicc/ 二.配置.编译.安装 下载完成后解压:sh ...
- 面试复习题(一)Java系列
(根据自己的理解和根据黑马资料总结—意见不统一我会写上自己的理解) 一.Java面向对象 1.面向对象都有哪些特性以及你对这些特性的理解 继承.封装.多态.(抽象) 2.public,private, ...
- 解决 Jenkins 乱码以及命令不存在的问题
方法一: Jenkins----系统管理----系统设置----全局属性----勾选环境变量 键 LANG 值 zh_CN.UTF-8 方法二(如果脚本用的是python): PYTHONIOENCO ...
- RWD(Responsive Web Design)(转)
The key point is adapting to the user’s needs and device capabilities. Suppose a mobile user will be ...
- centos7安装kong和kong-dashboard
1.安装Kong yum install -y https://kong.bintray.com/kong-community-edition-rpm/centos/7/kong-community- ...