【写在前面】

有时候看到大神们的代码,偶尔会用到@来装饰函数。当时查了资料,大致了解装饰器一般用于在不改变原函数的基础上 ,对原函数功能进行修改/增强。使用场景是:日志级别设置、权限校验、性能测试等。

在当前工作中,还没具体使用到这一神器。所以想着,先了解下装饰器的使用方法,方便以后工作时用到。

【小碎步走起来】

1、实现a+b的功能

def A(a, b):
print(a + b)
return a + b
if __name__ == "__main__":
A(1, 2)

2、现在我想函数A不变的情况下,实现a+2+b*2的功能  -- 函数带参数或者参数数量不确定

def B(fun):
def C(*args):
a = args[0]+2
b = args[1]*2
return fun(a,b)
return C
@B
def A(a, b):
print(a + b)
return a + b
if __name__ == "__main__":
A(1, 2) 输出结果:7

(1)在main函数运行A(1,2)时,先进入装饰器B中,并将a/b参数传给*args(这里args可表示不限数量的变量输入);在对参数a/b进行修改后,最后进入A函数进行 计算。

(2)函数B的入参是 fun,函数C的入参是 args,对应的实际值即为A(),(a,b)

3、在添加装饰器后,又想继续使用原函数功能 -- 装饰器带参数

def D(flag):
def B(fun):
def C(*args):
if flag:
a = args[0]+2
b = args[1]*2
return fun(a, b)
else:
return fun(*args)
return C
return B @D(flag=False)
def A(a, b):
print(a + b)
return a + b if __name__ == "__main__":
A(1, 2) 输出结果:3

通过flag字段的判断,可以实现A()原功能或者A的增加功能。

这里要注意下,在原装饰器B函数外面又加了一层函数D,为 了加深印象,可 以这样理解:

D是为 了flag参数的,B是为了A()的,C是为了a/b参数的。对应的顺序是基于flag/A/ab的上下文决定。

4、在写完函数D后,发现又想 加新功能,怎么办? -- 装饰器叠罗汉。

# coding=utf-8
# @Auther : "鹏哥贼优秀"
# @Date : 2019/10/24
# @Software : PyCharm
def D(flag):
def B(fun):
def C(*args):
print("我是D 装饰器")
print("当前输入值内容变为:", *args)
if flag:
a = args[0] + 2
b = args[1] * 2
return fun(a, b)
else:
return fun(*args)
return C
return B def E(fun):
def F(*args):
print("我是E 装饰器")
print("当前输入值内容变为:",*args)
a = args[0] + 10
b = args[1] + 10
return fun(a, b)
return F @D(flag=True)
@E
def A(a, b):
print(a + b)
return a + b if __name__ == "__main__":
A(1, 2) 输出结果是:
我是D 装饰器
当前输入值内容变为:1 2
我是E 装饰器
当前输入值内容变为:3 4
27

当出现多个装饰器,按顺序分别进行对应功能的计算,因此根据以上示例代码,先进行装饰器D的计算,将a/b变为3/4;然后进入装饰器E的计算,将a/b变为了13/14,最后进入A()函数,并输出27。

【写在后面】

由于当前对装饰器了解不深,只是知道了大致的用法。因此先做个笔记,等以后翅膀硬了再来叨叨下。

(如果内容介绍有偏差或者不正确的地方,欢迎大家指正。)

作者:鹏哥贼优秀

@All开发者,想获取满满的技术干货吗?想了解最前沿的技术洞察吗?想得到最权威的学习认证吗?还有多维的交流平台以及有趣的有奖互动?

2020年华为开发者大会将于2月11-12日在深圳举办,这将是华为面向开发者群体的最顶级盛会,包含但不限于华为在云计算、人工智能、5G、IoT等多个领域,特别是智能计算双引擎鲲鹏和昇腾的最新创新与最佳实践,充满期待对吧,欢迎报名预约

【Python成长之路】python 基础篇 -- 装饰器【华为云分享】的更多相关文章

  1. (转)Python成长之路【第九篇】:Python基础之面向对象

    一.三大编程范式 正本清源一:有人说,函数式编程就是用函数编程-->错误1 编程范式即编程的方法论,标识一种编程风格 大家学习了基本的Python语法后,大家就可以写Python代码了,然后每个 ...

  2. python成长之路第三篇(1)_初识函数

    目录: 函数 为什么要使用函数 什么是函数 函数的返回值 文档化函数 函数传参数 文件操作(二) 1.文件操作的步骤 2.文件的内置方法 函数: 一.为什么要使用函数 在日常写代码中,我们会发现有很多 ...

  3. Python之路(第十一篇)装饰器

    一.什么是装饰器? 装饰器他人的器具,本身可以是任意可调用对象,被装饰者也可以是任意可调用对象. 强调装饰器的原则:1 不修改被装饰对象的源代码 2 不修改被装饰对象的调用方式 装饰器的目标:在遵循1 ...

  4. Python成长之路【第二篇】Python基础之数据类型

    阅读目录 简介 1 什么是数据? x=10,10是我们要存储的数据 2 为何数据要分不同的类型 数据是用来表示状态的,不同的状态就应该用不同的类型的数据去表示 3 数据类型 数字(整形,长整形,浮点型 ...

  5. python成长之路【第九篇】:网络编程

    一.套接字 1.1.套接字套接字最初是为同一主机上的应用程序所创建,使得主机上运行的一个程序(又名一个进程)与另一个运行的程序进行通信.这就是所谓的进程间通信(Inter Process Commun ...

  6. python成长之路【第二篇】:列表和元组

    1.数据结构数据结构是通过某种方式(例如对元素进行编号)组织在一起的数据元素的集合,这些数据元素可以是数字或者字符,甚至可以是其他数据结构.在Python中,最基本的数据结构是序列(sequence) ...

  7. python成长之路【第一篇】:python简介和入门

    一.Python简介 Python(英语发音:/ˈpaɪθən/), 是一种面向对象.解释型计算机程序设计语言. 二.安装python windows: 1.下载安装包 https://www.pyt ...

  8. python成长之路第三篇(4)_作用域,递归,模块,内置模块(os,ConfigParser,hashlib),with文件操作

    打个广告欢迎加入linux,python资源分享群群号:478616847 目录: 1.作用域 2.递归 3.模块介绍 4.内置模块-OS 5.内置模块-ConfigParser 6.内置模块-has ...

  9. python成长之路第三篇(3)_内置函数及生成器迭代器

    打个广告欢迎加入linux,python资源分享群群号:478616847 目录: 1.lambda表达式 2.map内置函数 3.filter内置函数 4.reduce内置函数 5.yield生成器 ...

随机推荐

  1. Intellij IDEA配置JDK、Maven和Tomcat

    一.配置JDK 1.File-->Project Structure 2.选择SDKs 3.点击+号添加自己本地jdk的安装目录,保存即可 二.配置Maven 1.File -> Othe ...

  2. 小白学 Python(22):time 和 calendar 模块简单使用

    人生苦短,我选Python 前文传送门 小白学 Python(1):开篇 小白学 Python(2):基础数据类型(上) 小白学 Python(3):基础数据类型(下) 小白学 Python(4):变 ...

  3. R画图——分屏

    最近项目需求,用R画了一个九宫格的图,第一次画,将简化后的脚本呈现一下,不是有人说,既然做了,那就摆出来吧. *中文行为说明: args <- commandArgs(T) 调用命令行读取 fi ...

  4. kafka线上滚动升级方案记录

    kafka升级方案 为什么进行kafka升级 一.修改unclean.leader.election.enabled默认值Kafka社区终于下定决心要把这个参数的默认值改成false,即不再允许出现u ...

  5. 多线程编程(3)——synchronized原理以及使用

    一.对象头 通常在java中一个对象主要包含三部分: 对象头 主要包含GC的状态..类型.类的模板信息(地址).synchronization状态等,在后面介绍. 实例数据:程序代码中定义的各种类型的 ...

  6. 自制window下core animation引擎 - demo第二弹 - 仿QQ电脑管家加速小火箭

    一年前想写一个像cocoa那样,可以方便层动画开发的引擎,写着写着又逆向它的QuartzCore.framework,也就是CoreAnimation的底层,已经大半年没有搞windows这个引擎.大 ...

  7. class继承关键字extends和super

    // 父类 class person { constructor (name,age) { this.name = name this.age = age } } class CheChinese e ...

  8. vue引用组件的两个方法

    <template> <div> <myComponent></myComponent> </div> </template> ...

  9. Openlayers ol.interaction.Select取消默认选中效果

    说明: 在使用ol.interaction.Select进行点击查询时,默认会把点击选中的要素显示在地图上 我的需求是做轨迹回放,并可以点击轨迹上某一点,进行查询.这时候如果重新播放轨迹,会发现这个选 ...

  10. SpringBoot学习(六)—— springboot快速整合RabbitMQ

    目录 Rabbit MQ消息队列 简介 Rabbit MQ工作模式 交换机模式 引入RabbitMQ队列 代码实战 Rabbit MQ消息队列 @ 简介 优点 erlang开发,并发能力强. 社区活跃 ...