[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.高阶函数 高阶函 ...
随机推荐
- Kubernetes(k8s)集群安装
一:简介 二:基础环境安装 1.系统环境 os Role ip Memory Centos 7 master01 192.168.25.30 4G Centos 7 node01 192.168.25 ...
- Spring注解之@RestControllerAdvice
前言 前段时间部门搭建新系统,需要出异常后统一接口的返回格式,于是用到了Spring的注解@RestControllerAdvice.现在把此注解的用法总结一下. 用法 首先定义返回对象Respons ...
- 关于Jvm的见解(二)
栈管运行,堆管存储!!! 栈呢,也叫作栈内存,主要管java程序的运行,在线程创建时创建,生命周期和线程一致,只要线程一结束,该栈就被GC,是线程私有的.基本类型的变量和对象的引用数据类型的变量都在栈 ...
- nyoj 813-对决 (i*j == k)
813-对决 内存限制:64MB 时间限制:1000ms 特判: No 通过数:11 提交数:23 难度:0 题目描述: Topcoder 招进来了 n 个新同学,Yougth计划把这个n个同学分成两 ...
- vue动态样式设置
思路: 通过 v-bind:class="true ? style1 : style2 " 配合三元表达式完成样式的切换 具体实现 //return设置控制的参数 //有多个需要样 ...
- electron——dialog(实现导出excel)
背景 前端点击导出excel按钮后,请求完需要导出的数据后发送给主进程electron,由主进程保存到本地 dialog 显示用于打开和保存文件.警报等的本机系统对话框. dialog 模块提供了ap ...
- canvas入门,就是这个feel!
钙素 Canvas 是在HTML5中新增的标签用于在网页实时生成图像,并且可以操作图像内容,基本上它是一个可以用JavaScript操作的位图.也就是说我们将通过JS完成画图而不是css. canva ...
- PHP抓取远程图片教程(包含不带后缀图片)
之前做微信登录开发时候,发现微信头像图片没有后缀名,传统的图片抓取方式不奏效,需要特殊的抓取处理.所以,后来将各种情况结合起来,封装成一个类,分享出来. 创建项目 作为演示,我们在www根目录创建项目 ...
- 20191017-6alpha week 2/2 Scrum立会报告+燃尽图 05
此作业要求参见https://edu.cnblogs.com/campus/nenu/2019fall/homework/9802 一.小组情况 队名:扛把子 组长:迟俊文 组员:宋晓丽 梁梦瑶 韩昊 ...
- vue 解决跨域
先上报错 以表尊重 在vue中 找到 config文件夹中的 index.js文件 配置更改如下 proxyTable: { '/api': { target: 'http://47.240.11. ...