【写在前面】

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

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

【小碎步走起来】

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. Topshelf+Quatz.Net的简单使用

    Topshelf+Quatz.Net的简单使用 一  Topshelf概述 Topshelf是创建Windows服务的另一种方法,老外的一篇文章Create a .NET Windows Servic ...

  2. 远程传输命令scp

    Linux scp 命令用于 Linux 之间复制文件和目录. scp 是 secure copy 的缩写, scp 是 linux 系统下基于 ssh 登陆进行安全的远程文件拷贝命令. scp 是加 ...

  3. Spring mvc之源码 handlerMapping和handlerAdapter分析

    Spring mvc之源码 handlerMapping和handlerAdapter分析 本篇并不是具体分析Spring mvc,所以好多细节都是一笔带过,主要是带大家梳理一下整个Spring mv ...

  4. ReactJS的4行代码

    Angular 2一个显著的变动是,把Angular 1的Promise pattern改成了Observer pattern,并且使用了ReactJS.这里有一篇值得一读的文章 要搞懂ReactJS ...

  5. thinkphp 6.0 在 initialize 中重定向无效

    thinkphp 6.0 在 initialize 中重定向无效 改用 header() 函数 实例: // header('location:/index.php/模块/控制器/方法'); head ...

  6. nyoj 22-素数求和问题(打表)

    22-素数求和问题 内存限制:64MB 时间限制:3000ms Special Judge: No accepted:41 submit:52 题目描述: 现在给你N个数(0<N<1000 ...

  7. 【前端知识体系-JS相关】JS-Web-API总结

    2.1 DOM操作 2.1.1 DOM的本质是什么? <!-- DOM树:二叉树 --> /* <?xml version="1.0" encoding=&quo ...

  8. 力扣(LeetCode)单值二叉树 个人题解

    如果二叉树每个节点都具有相同的值,那么该二叉树就是单值二叉树. 只有给定的树是单值二叉树时,才返回 true:否则返回 false. 示例 1: 输入:[1,1,1,1,1,null,1] 输出:tr ...

  9. gitbook怎么操作

    首先我先说一下什么是GitBook,它和Git没半毛钱关系,定义如下: GitBook 是一个基于 Node.js 的命令行工具,支持 Markdown 和 AsciiDoc 两种语法格式,可以输出 ...

  10. epoll介绍及使用

    小程序功能:简单的父子进程之间的通讯,子进程负责每隔1s不断发送"message"给父进程,不需要跑多个应用实例,不需要用户输入. 首先上代码 #include<assert ...