第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)

函数名: timeraddinner

函数体:除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 装饰器解析的更多相关文章

  1. 净心诀---python3装饰器

    python3装饰器 装饰器作用 简单理解:可以为已有函数添加额外功能 例: 已有2个函数如下 def MyFunc1(): print("This is a print function1 ...

  2. JS 装饰器解析

    随着 ES6 和 TypeScript 中类的引入,在某些场景需要在不改变原有类和类属性的基础上扩展些功能,这也是装饰器出现的原因. 装饰器简介 作为一种可以动态增删功能模块的模式(比如 redux ...

  3. python3 装饰器应用举例

    [引子] python 中的装饰器是oop(面向对象编程)设计模式.之装饰器模式的一个应用.由于有语法糖衣的缘故.所以写起来也更加方便 [从一个比较经典的应用场景来讲解装饰器] 有过一定编程经历的工程 ...

  4. python3 装饰器全解

    本章结构: 1.理解装饰器的前提准备 2.装饰器:无参/带参的被装饰函数,无参/带参的装饰函数 3.装饰器的缺点 4.python3的内置装饰器 5.本文参考 理解装饰器的前提:1.所有东西都是对象( ...

  5. python3 装饰器

    #Author by Andy#_*_ coding:utf-8 _*_#装饰器的原则及构成:# 原则:# 1.不能修改被装饰函数的源代码.# 2.不能修改被装饰函数的调用方式.# 3.不能改变被装饰 ...

  6. python3 装饰器初识 NLP第三条

    还是先抄一条NLP假设... 三,有效果比有道理更重要   光说做法有道理或者正确而不顾是否有效果,是在自欺欺人. 在三赢(我好,人好,世界好)的原则基础上追求效果,比坚持什么是对的更有意义. 说道理 ...

  7. python3装饰器用法示例

    装饰器在编写后台的逻辑时有可能会用到,比方说一个场景:公司的员工想要登录自己公司的考勤记录系统去修改自己的考勤,以前是随便谁都有权限去修改,这样老板不同意了,现在,要在你登录前加一个权限验证的逻辑,如 ...

  8. python3装饰器

    由于函数也是一个对象,而且函数对象可以被赋值给变量,所以,通过变量也能调用该函数. >>> def now(): ... print('2015-3-25') ... >> ...

  9. python3 装饰器修复技术@wraps到底是什么?

    Python 装饰器中的@wraps的作用:    装饰器的作用:    在不改变原有功能代码的基础上,添加额外的功能,如用户验证等    @wraps(view_func)的作用:     不改变使 ...

随机推荐

  1. Flutter学习笔记(35)--通知Notification

    如需转载,请注明出处:Flutter学习笔记(35)--通知Notification 通知的NotificationListener和我们之前写的事件的Listener一样,都是功能性的组件,而且也都 ...

  2. 谈谈java中的并发(一)

    一.并发的定义 并发:对于这个概念一直就是没怎么搞懂,就是感觉特别的生疏,(自己从从字面上理解就是多个东西,一起出发),所以就上网上查了一些资料: 同时拥有两个或多个线程,如果程序在单核处理器上运行, ...

  3. 一位老程序员说,有这份python3的开发指南,月薪能突破20K

    推荐视频: AI人工智能识别技术_第一节AI人工智能识别技术_第二节Python基础案例之教你如何查询对方IP_第一节Python基础案例之教你如何查询对方IP_第二节 有程序员说,这份python3 ...

  4. Java 中的数据结构类 Vector 和 ArrayList

    今天刷算法题目时,使用到了 Java 的内置栈类 Stack,好奇它是怎么实现的,发现它是继承于 Vector 这个类.那么,就先学习下 Vector 这个类的实现吧! Vector 和 ArrayL ...

  5. 10、一个action中处理多个方法的调用第一种方法动态调用

    我们新建一个用户的action package com.weiyuan.test; import com.opensymphony.xwork2.ActionSupport; /** * * 这里不用 ...

  6. Java 多线程基础(十二)生产者与消费者

    Java 多线程基础(十二)生产者与消费者 一.生产者与消费者模型 生产者与消费者问题是个非常典型的多线程问题,涉及到的对象包括“生产者”.“消费者”.“仓库”和“产品”.他们之间的关系如下: ①.生 ...

  7. 计算机网络之DDOS

    1.什么是DDOS DDOS(Distributed Denial of Service),中文意思为“分布式拒绝服务”,就是利用大量合法的分布式服务器对目标发送请求,从而导致正常合法用户无法获得服务 ...

  8. 入门大数据---Flink开发环境搭建

    一.安装 Scala 插件 Flink 分别提供了基于 Java 语言和 Scala 语言的 API ,如果想要使用 Scala 语言来开发 Flink 程序,可以通过在 IDEA 中安装 Scala ...

  9. js语法基础入门(1)

    1.基础入门 1.1.hello world 1.1.1.JavaScript是什么? JavaScript是一门跨平台.面向对象的轻量级脚本语言,在web开发中被广泛应用 1.1.2.JavaScr ...

  10. JavaScript基础函数的声明(014)

    1.函数的重要地位 函数(functions)在JavaScript里有着重要的地位,其原因有二: 它们是一种特殊的对象 它们提供作用域 说函数在JavaScript里是特殊的对象,因为: 程序的执行 ...