参考链接: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 再谈装饰器的更多相关文章

  1. python再议装饰器

    装饰器实质还是一个函数,是对其他函数进行装饰的函数.装饰器函数接受被装饰函数的函数名,返回被装饰函数的函数名.对一个函数进行装饰有两个原则:一是不能修改被装饰函数的源代码:二是被装饰函数的调用方式不可 ...

  2. [TimLinux] Python 再谈元类 metaclass

    本博文通过对以下链接进行理解后,编写. https://stackoverflow.com/questions/100003/what-are-metaclasses-in-python 1. 类 类 ...

  3. 浅显易懂的谈一谈python中的装饰器!!

    hello大家好~~我是稀里糊涂林老冷,一天天稀里糊涂的. 前一段时间学习了装饰器,觉着这东西好高大上哇靠!!哈哈,一定要总结一下,方便以后自己查阅,也希望帮助其他伙伴们共同进步! 装饰器: 大家可以 ...

  4. python之路——装饰器函数

    阅读目录 楔子 装饰器的形成过程 开放封闭原则 谈装饰器主要功能和装饰器固定结构 带参数的装饰器 多个装饰器装饰一个函数 返回顶部 楔子 作为一个会写函数的python开发,我们从今天开始要去公司上班 ...

  5. python之路---装饰器函数

    阅读目录 楔子 装饰器的形成过程 开放封闭原则 谈装饰器主要功能和装饰器固定结构 带参数的装饰器 多个装饰器装饰一个函数 返回顶部 楔子 作为一个会写函数的python开发,我们从今天开始要去公司上班 ...

  6. python高级之装饰器

    python高级之装饰器 本节内容 高阶函数 嵌套函数及闭包 装饰器 装饰器带参数 装饰器的嵌套 functools.wraps模块 递归函数被装饰 1.高阶函数 高阶函数的定义: 满足下面两个条件之 ...

  7. Day04 - Python 迭代器、装饰器、软件开发规范

    1. 列表生成式 实现对列表中每个数值都加一 第一种,使用for循环,取列表中的值,值加一后,添加到一空列表中,并将新列表赋值给原列表 >>> a = [0, 1, 2, 3, 4, ...

  8. Noah的学习笔记之Python篇:装饰器

    Noah的学习笔记之Python篇: 1.装饰器 2.函数“可变长参数” 3.命令行解析 注:本文全原创,作者:Noah Zhang  (http://www.cnblogs.com/noahzn/) ...

  9. 第二篇:python高级之装饰器

    python高级之装饰器   python高级之装饰器 本节内容 高阶函数 嵌套函数及闭包 装饰器 装饰器带参数 装饰器的嵌套 functools.wraps模块 递归函数被装饰 1.高阶函数 高阶函 ...

随机推荐

  1. php [poolwww] seemsbusy (youmayneedto increasepm.start_servers, or pm.min/max_spare_servers)错误解决方法

    php [poolwww] seemsbusy (youmayneedto increasepm.start_servers, or pm.min/max_spare_servers)错误解决方法修改 ...

  2. PHP对象继承

    PHP对象继承<?php class foo{ public function printItem($string) { echo 'Foo: ' . $string . PHP_EOL; } ...

  3. ActiveMQ消息队列从入门到实践(1)—JMS的概念和JMS消息模型

    1. 面向消息的中间件 1.1 什么是MOM 面向消息的中间件,Message Oriented Middleware,简称MOM,中文简称消息中间件,利用高效可靠的消息传递机制进行平台无关的数据交流 ...

  4. 关于GDAL读写Shp乱码的问题总结

    目录 1. 正文 1.1. shp文件本身的编码的问题 1.2. 设置读取的编码方式 1.2.1. GDAL设置 1.2.2. 解码方式 1.2.3. 其他 2. 参考 1. 正文 最近在使用GDAL ...

  5. 点击a标签的时候出现虚影

    在a标签中添加 outline:none;就可以去除了

  6. [ERROR]Unable to locate package

    刚更换了DNS,需要更新下apt-get $ apt-get update

  7. django 中 css文件的调用

    Django: 配置css文件 晚上搞了好久的css文件的调用,发现,我根本文件位置都放错了. 接下来要更改settings.py 和 urls.py 的设定. Settings.py 中应该: ur ...

  8. Java描述设计模式(22):策略模式

    本文源码:GitHub·点这里 || GitEE·点这里 一.生活场景 每年双十一,各大电商平台会推出不同的满减策略,当用户的消费金额满一定额度后,会进行减去一定的优惠额度,从而来一波清仓甩卖,使用策 ...

  9. 官方宣布IPV4已然耗尽,IPv6D风口或将到来?

    急救箱 IPV4真的用完了吗? ​ IPV4真的用完了吗?其实 小兰 一点也不惊讶 ,毕竟全球人口这么多,多N的几次幂就用完了吧- 43亿个IPv4地址已分配完毕,这意味着没已经有更多的IPv4地址可 ...

  10. 20191107-5 beta week 2/2 Scrum立会报告+燃尽图 04

    此作业的要求参见https://edu.cnblogs.com/campus/nenu/2019fall/homework/9957 一.小组情况 队名:扛把子 组长:孙晓宇 组员:宋晓丽 梁梦瑶 韩 ...