Python3 装饰器解析
第6章 函数
6.1 函数的定义和调用
6.2 参数传递
6.3 函数返回值
6.4 变量作用域
6.5 匿名函数(lambda)
6.6 递归函数
6.7 迭代器
6.8 生成器
6.9 装饰器
6.9 装饰器
装饰器本质上是一个 Python 函数或类,它可以让其他函数或类在不需要做任何代码修改的前提下增加额外功能,它也不会改变函数或类的调用方式。
它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景,装饰器是解决这类问题的绝佳设计。有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码到装饰器中并继续重用。
概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。
装饰器的语法是将@装饰器名,放在被装饰对象上面。
有两类装饰器:函数装饰器、类装饰器
# 函数装饰器的语法
@dec
def func():
pass
参数说明:
@称为语法糖
dec:装饰器名字
func:被装饰的函数名
在介绍装饰器之前,先明确几个概念及原则:
原则:
Python程序是从上往下顺序执行的,而且碰到函数的定义代码块是不会立即执行的,只有等到该函数被调用时,才会执行其内部的代码块。
如果一个函数定义了两次,那么后面定义的会覆盖前面的定义。
在Python中代码的放置位置是有区别的,不能随意摆放,通常函数体要放在调用的语句之前。
概念:
函数名、函数体、返回值,函数的内存地址、函数名加括号、函数名被当作参数、函数名加括号被当作参数、返回函数名、返回函数名加括号。
# 加操作:无参数
import time
def timer(func):
def inner():
t1 = time.time()
func()
t2 = time.time()
return t2 - t1
return inner
@timer
def add():
a = 1
b = 1
time.sleep(1)
c = a + b
print(c)
return c
add = add()
print(add)
函数名: timer
、add
、inner
函数体:除def那一行外的部分
返回值: return后面的表达式
函数的内存地址:id(add)
、id(outer)
等等
函数名加括号:对函数进行调用,比如add()
、timer(func)
函数名作为参数: timer(func)
中的func
本身是个函数,但作为参数被传递给了timer函数
函数名加括号被当做参数:其实就是先调用函数,再将它的返回值当做别的函数的参数,例如timer(add())
返回函数名:return inner
返回函数名加括号:return inner()
,其实就是先执行inner函数,再将其返回值作为别的函数的返回值。
一个装饰器例子:
'''
1、@timer,称为语法糖,其作用是将被装饰函数add的函数名作为实参传给装饰器timer函数的形参func,传函数名实际传的是内存指向;
2、函数timer内又嵌套了inner函数,返回值是函数名inner,必须要明确的是,传进去函数名add,返回来inner函数名,结果就是add和inner共同指向在内存中定义inner的起始地址,而此时形参func指向在内存定义add的起始地址,可在调试程序过程中通过id方法打印查看add和inner所指向的内存地址的变化情况。
明确这两点,装饰器就不难理解了。
'''
# 加操作:无参数
import time
def timer(func):
def inner():
t1 = time.time()
func()
t2 = time.time()
return t2 - t1
return inner
@timer
def add():
a = 1
b = 1
time.sleep(1)
c = a + b
print(c)
return c
add = add()
print(add)
# 加操作:位置参数
import time
def timer(func):
def inner(a, b):
t1 = time.time()
func(a, b)
t2 = time.time()
return t2 - t1
return inner
@timer
def add(a, b):
# a = 1
# b = 1
time.sleep(1)
c = a + b
print(c)
return c
add = add(1, 1)
print(add)
# 加操作:可变参数
import time
def timer(func):
def inner(*args):
t1 = time.time()
func(*args)
t2 = time.time()
return t2 - t1
return inner
@timer
def add(a, b):
# a = 1
# b = 1
time.sleep(1)
c = a + b
print(c)
return c
add = add(1, 1)
print(add)
# 加减乘除操作:可变参数
import time
def timer(func):
def inner(*args):
t1 = time.time()
func(*args)
t2 = time.time()
return t2 - t1
return inner
@timer
def add(a, b):
# a = 1
# b = 1
time.sleep(1)
c = a + b
print(c)
return c
@timer
def plus(a, b):
# a = 1
# b = 1
time.sleep(2)
c = a - b
print(c)
return c
@timer
def multi(a, b):
# a = 1
# b = 1
time.sleep(3)
c = a * b
print(c)
return c
@timer
def div(a, b):
# a = 1
# b = 1
time.sleep(4)
c = a / b
print(c)
return c
add = add(1, 1)
print(add)
plus = plus(2, 1)
print(plus)
multi = multi(3, 1)
print(multi)
div = div(4, 1)
print(div)
敬请关注个人微信公众号:测试工匠麻辣烫
Python3 装饰器解析的更多相关文章
- 净心诀---python3装饰器
python3装饰器 装饰器作用 简单理解:可以为已有函数添加额外功能 例: 已有2个函数如下 def MyFunc1(): print("This is a print function1 ...
- JS 装饰器解析
随着 ES6 和 TypeScript 中类的引入,在某些场景需要在不改变原有类和类属性的基础上扩展些功能,这也是装饰器出现的原因. 装饰器简介 作为一种可以动态增删功能模块的模式(比如 redux ...
- python3 装饰器应用举例
[引子] python 中的装饰器是oop(面向对象编程)设计模式.之装饰器模式的一个应用.由于有语法糖衣的缘故.所以写起来也更加方便 [从一个比较经典的应用场景来讲解装饰器] 有过一定编程经历的工程 ...
- python3 装饰器全解
本章结构: 1.理解装饰器的前提准备 2.装饰器:无参/带参的被装饰函数,无参/带参的装饰函数 3.装饰器的缺点 4.python3的内置装饰器 5.本文参考 理解装饰器的前提:1.所有东西都是对象( ...
- python3 装饰器
#Author by Andy#_*_ coding:utf-8 _*_#装饰器的原则及构成:# 原则:# 1.不能修改被装饰函数的源代码.# 2.不能修改被装饰函数的调用方式.# 3.不能改变被装饰 ...
- python3 装饰器初识 NLP第三条
还是先抄一条NLP假设... 三,有效果比有道理更重要 光说做法有道理或者正确而不顾是否有效果,是在自欺欺人. 在三赢(我好,人好,世界好)的原则基础上追求效果,比坚持什么是对的更有意义. 说道理 ...
- python3装饰器用法示例
装饰器在编写后台的逻辑时有可能会用到,比方说一个场景:公司的员工想要登录自己公司的考勤记录系统去修改自己的考勤,以前是随便谁都有权限去修改,这样老板不同意了,现在,要在你登录前加一个权限验证的逻辑,如 ...
- python3装饰器
由于函数也是一个对象,而且函数对象可以被赋值给变量,所以,通过变量也能调用该函数. >>> def now(): ... print('2015-3-25') ... >> ...
- python3 装饰器修复技术@wraps到底是什么?
Python 装饰器中的@wraps的作用: 装饰器的作用: 在不改变原有功能代码的基础上,添加额外的功能,如用户验证等 @wraps(view_func)的作用: 不改变使 ...
随机推荐
- ASP.NET处理管道之防盗链
盗链就是在用户向网站a请求网站资源时,网站a将网站资源的路径填写为b网站资源的地址,用户将直接看到网站a上显示着网站b的资源,从而造成盗链. 要防止盗链,就要用到处理管道中的技术 在相应的模块类中: ...
- 手机U盘制作成系统启动盘后在手机端无法识别
本人最近用手机U盘做了个系统启动盘,突然发现U盘再次插到手机的时候,手机无法识别出U盘了,于是百度了一下,百度结果大概是跟U盘的格式有关.结果我想起了之前用的DiskGenius可以看到u盘的隐藏盘符 ...
- Ubuntu搭建Java开发环境-刘志敏-专题视频课程
Ubuntu搭建Java开发环境-3人已学习 课程介绍 主要介绍在Ubuntu环境如何安装Java开发的基本环境课程收益 学会Ubuntu中安装jdk.mysql.maven和id ...
- 手写React的Fiber架构,深入理解其原理
熟悉React的朋友都知道,React支持jsx语法,我们可以直接将HTML代码写到JS中间,然后渲染到页面上,我们写的HTML如果有更新的话,React还有虚拟DOM的对比,只更新变化的部分,而不重 ...
- yum 安装JDK
系统:CentOS 7 查看当前系统是否已安装JDK yum list installed |grep java 如果没有就选择yum库中的包进行安装,查看yum库中JDK列表 yum -y list ...
- Python3-socket模块-低级网络接口
Python3中的socket模块提供了对访问套接字(socket)的接口 socket可以理解为是一个管道,通过这个管道可以使两个不同的程序通过网络进行通信,在Python中的scoket()函数可 ...
- Python 简明教程 --- 7,Python 字符串
微信公众号:码农充电站pro 个人主页:https://codeshellme.github.io 过早的优化代码是罪恶之源. -- Donald Knuth 目录 无论哪种编程语言,字符串处理都是最 ...
- 入门大数据---Spark_Streaming与流处理
一.流处理 1.1 静态数据处理 在流处理之前,数据通常存储在数据库,文件系统或其他形式的存储系统中.应用程序根据需要查询数据或计算数据.这就是传统的静态数据处理架构.Hadoop 采用 HDFS 进 ...
- asp.net Core依赖注入(自带的IOC容器)
今天我们主要讲讲如何使用自带IOC容器,虽然自带的功能不是那么强大,但是胜在轻量级..而且..不用引用别的库. 在新的ASP.NET Core中,大量的采用了依赖注入的方式来编写代码. 比如,在我们的 ...
- 如何在Linux下使用Tomcat部署Web应用(图文)
学习Java必不可少的视同Tomcat,但是如果不会使用tomcat部署项目,那也是白扯,在这里教大家如果在Linux系统下视同Tomcat部署Web应用. 工具/原料 Apache-tomc ...