[TimLinux] Python 再谈装饰器
参考链接:https://stackoverflow.com/questions/739654/how-to-make-a-chain-of-function-decorators
1. 函数对象
- 能够赋值给其他变量
- 能够在另外函数内定义
- 能够作为参数进行传递
- 能够作为函数的返回值
def firstLevel(f_arg): # 作为参数,可以赋值
def tmp_func(*args, **kwargs): # 可以在另外函数内定义
# do something ...
ret = f_arg(*args, **kwargs)
# do something ...
return ret
return tmp_func # 作为函数的返回值 # 1. 原始方法
def func(*args, **kwargs):
print("In func")
func = firstLevel(func) # 2. 装饰器方法
@firstLevel
def func(*args, **kwargs):
print("In func") # 使用
func()
2. 多层装饰器
可以对函数进行一层又一层的包装,使用多层装饰器即可
def firstLevel(f_arg):
def tmp_func(*args, **kwargs):
print("----s.firstLevel----")
ret = f_arg(*args, **kwargs)
print("----e.firstLevel----")
return ret
return tmp_func def secondLevel(f_arg):
def tmp_func(*args, **kwargs):
print("----s.secondLevel----")
ret = f_arg(*args, **kwargs)
print("----e.secondLevel----")
return ret
return tmp_func #1. 原始方法
def func(*args, **kwargs):
print("In func")
func = firstLevel(secondLevel(func))
func() # 2. 装饰器方法
@firstLevel
@secondLevel
def func(*args, **kwargs):
print("In func")
func()
@firstLevel 语法,
这个后面看似隐藏了一对(),用来将下面的代码作为装饰器函数返回的内部函数的参数进行传递,当明确指定()的时候,则是给装饰器函数传递参数,
3. 装饰器接收参数
@firstLevel 语法,告诉我们这个函数接收的参数是一个函数对象,内部返回的是一个函数(firstLevel就是函数名,使用@标记告诉我们的)
@firstLevel(arg1, arg2, ...) 语法,告诉我们这个firstLevel(arg1, arg2, ...) 函数接收参数,返回的也是一个函数,返回的函数比如叫 retLevel,则将转化为: @retLevel 语法,retLevel 语法就跟上面的语法一样,告诉我们返回的 retLevel 接收的参数是一个函数对象,内部同样返回了一个函数 (retLevel 就是中间函数名,使用@标记告诉我们的)
def firstLevel(arg1, arg2):
# do something ...
print(arg1, arg2)
# 使用参数做一些事情(这是函数传递参数的目的)
def tmpRetLevel(f_arg):
def tmp_func(*args, **kwargs):
# do something ...
ret = f_arg(*args, **kwargs)
# do something ...
return ret
return tmp_func return tmpRetLevel # 1. 原始方法
def func(*args, **kwargs):
print("In func") retLevel = firstLevel('', '')
func = retLevel(func)
func('', '') # 2. 装饰器方法
@firstLevel('', '')
def func(*args, **kwargs):
print("In func") func('', '')
4. functools实现装饰器
上面的返回后的函数,打印一些内部变量比如:func.__doc__, __name__ 将变为 内部函数的 __doc__,__name__ 描述信息,functools.wraps将解决这样的问题,wraps()函数本身就是一个装饰器。
import functools def firstLevel(f_arg):
@functools.wraps(f_arg):
def tmpFunc(*args, **kwargs):
# do something ...
ret = f_arg(*args, **kwargs)
# do something ...
return ret
return tmpFunc @firstLevel
def func(*args, **kwargs):
print("In func") print(func.__name__) # 输出:func
4. 使用场景
- 装饰外部提供的库
- 避免大量重复代码的编写
- 比如:Django对视图的权限控制,Twisted将函数修改为异步调用
[TimLinux] Python 再谈装饰器的更多相关文章
- python再议装饰器
装饰器实质还是一个函数,是对其他函数进行装饰的函数.装饰器函数接受被装饰函数的函数名,返回被装饰函数的函数名.对一个函数进行装饰有两个原则:一是不能修改被装饰函数的源代码:二是被装饰函数的调用方式不可 ...
- [TimLinux] Python 再谈元类 metaclass
本博文通过对以下链接进行理解后,编写. https://stackoverflow.com/questions/100003/what-are-metaclasses-in-python 1. 类 类 ...
- 浅显易懂的谈一谈python中的装饰器!!
hello大家好~~我是稀里糊涂林老冷,一天天稀里糊涂的. 前一段时间学习了装饰器,觉着这东西好高大上哇靠!!哈哈,一定要总结一下,方便以后自己查阅,也希望帮助其他伙伴们共同进步! 装饰器: 大家可以 ...
- python之路——装饰器函数
阅读目录 楔子 装饰器的形成过程 开放封闭原则 谈装饰器主要功能和装饰器固定结构 带参数的装饰器 多个装饰器装饰一个函数 返回顶部 楔子 作为一个会写函数的python开发,我们从今天开始要去公司上班 ...
- python之路---装饰器函数
阅读目录 楔子 装饰器的形成过程 开放封闭原则 谈装饰器主要功能和装饰器固定结构 带参数的装饰器 多个装饰器装饰一个函数 返回顶部 楔子 作为一个会写函数的python开发,我们从今天开始要去公司上班 ...
- python高级之装饰器
python高级之装饰器 本节内容 高阶函数 嵌套函数及闭包 装饰器 装饰器带参数 装饰器的嵌套 functools.wraps模块 递归函数被装饰 1.高阶函数 高阶函数的定义: 满足下面两个条件之 ...
- Day04 - Python 迭代器、装饰器、软件开发规范
1. 列表生成式 实现对列表中每个数值都加一 第一种,使用for循环,取列表中的值,值加一后,添加到一空列表中,并将新列表赋值给原列表 >>> a = [0, 1, 2, 3, 4, ...
- Noah的学习笔记之Python篇:装饰器
Noah的学习笔记之Python篇: 1.装饰器 2.函数“可变长参数” 3.命令行解析 注:本文全原创,作者:Noah Zhang (http://www.cnblogs.com/noahzn/) ...
- 第二篇:python高级之装饰器
python高级之装饰器 python高级之装饰器 本节内容 高阶函数 嵌套函数及闭包 装饰器 装饰器带参数 装饰器的嵌套 functools.wraps模块 递归函数被装饰 1.高阶函数 高阶函 ...
随机推荐
- Git如何fork别人的仓库并作为贡献者提交代码
例如 要fork一份google的MLperf/inference代码,下面介绍具体做法:预备知识git里的参考有几种表示,分别是上游仓库,远程仓库和本地仓库,逻辑关系如下拉取代码的顺序:别的大牛的代 ...
- 小白历险记:spingboot之helloworld
还记得入职第一天的时候,先安装了相关的软件,配置了环境.boss叫我写的第一个程序:搭建一个springboot工程,输出helloworld. 哈哈话不多说,回忆一下. 1.打开IDEA,点击Cre ...
- 7月22 Linux作业-文件管理
习题内容 解答 1.答案 [root@centos7 ~]# echo '*/1 * * * * /usr/bin/cp /etc /data/`/usr/bin/date +\%Y-\%m-\%d` ...
- Python 常用模块系列学习(1)--random模块常用function总结--简单应用--验证码生成
random模块--random是一个生成器 首先: import random #导入模块 print (help(random)) #打印random模块帮助信息 常用function ...
- Docker基础与实战,看这一篇就够了
docker 基础 什么是Docker Docker 使用 Google 公司推出的 Go 语言 进行开发实现,基于 Linux 内核的 cgroup,namespace,以及 AUFS 类的 Uni ...
- 2018.3.7java 学习第二天
java 学习的第二天,首先我们要学习的是声明变量,在程序中,我们必须先声明变量,然后才可以去使用之,那么变量究竟是什么呢? 在很多课本上,有很多的定义诸如:“变量来源于数学,是计算机语言中能储存计算 ...
- HTTP,HTTPS,HTTP2笔记
HTTP 网络协议分层 应用层 -> HTTP FTP 为应用软件提供了很多服务 构建于TCP协议之上 屏蔽网络传输的相关细节 传输层 -> TCP UDP 向用户提供可靠的端对端的服务( ...
- Linux基础命令复习01
一.Linux中的基本查看.查找命令: 1.ls 查看目录信息: -l #查看属性,以长格式显示 -d #查看本身属性 -A #显示包括以.开头的隐藏文档 -h #提供易读的单位 -R #表示递 ...
- 面试官:你连RESTful都不知道我怎么敢要你?
目录 01 前言 02 RESTful的来源 03 RESTful6大原则 1. C-S架构 2. 无状态 3.统一的接口 4.一致的数据格式 4.系统分层 5.可缓存 6.按需编码.可定制代码(可选 ...
- Pod镜像拉取策略imagePullPolicy
默认值是IfNotPresent Always 总是拉取: 首先获取仓库镜像信息, 如果仓库中的镜像与本地不同,那么仓库中的镜像会被拉取并覆盖本地. 如果仓库中的镜像与本地一致,那么不会拉取镜像. 如 ...