参考链接:Python 函数装饰器

  我认为python中的装饰器是一个很厉害的功能,他能瞬间提升代码的逼格,但对于我这样的小白来说,别说为所欲为的使用了,就连简单的尝试一下,却也是难于登天。经过长达半年的努力,我终于找到了大部分装饰器的介绍信息,鲁迅曾经说过,良好的开始就代表了成功的一半,在我看来,鲁迅分明还是太保守,良好的开端无疑代表你已经成功了。比如接下来我们只需要Ctrl+C+V,就可以完成装饰器的学习了,亲爱的小朋友们,你们学会了吗?

给大人看的分割线


装饰器是用来给已经定义好的函数增加功能用的

1)不会改变原来的代码结构。

为什么这么说呢,因为相比于另一种方法:只将函数作为变量传入另一个函数从而来减少重合,使用装饰器并不需要将函数调用改写

#定义这个函数来为类似foo()的需要去增加loging.warn()的全部函数增添这个loging.warn()的功能
#假如有许多函数和foo()一样,都需要增加loging.warn()这行代码,我们就可以定义一个函数,然后将每个需要增加功能的函数作为参数传入
#但是这样必须在用use_logging(foo)去替换原有的foo()这就改变了函数的调用,破坏了原有的代码结构
def use_logging(func):logging.warn("%s is running" % func.__name__)func()def foo():print('i am foo')use_logging(foo)

2)装饰器在不修改函数代码的前提下影响代码的功能;调用python中的函数可以作为变量去传递,基于这一特性,我们可以构建出自己的装饰器;

先来了解一些基础知识:

  1)我们可以将函数作为变量传递。要注意括号,加了括号就会运行函数。

  2)在函数的内部还可以嵌套函数

def hi(name="yasoob"):print("现在在hi()里面运行")def greet():return "现在在greet()里面运行"def welcome():return "现在在welcom()里面运行"print(greet())print(welcome())print("现在你返回到了hi()里面")hi()
# 上面展示了无论何时你调用hi(), greet()和welcome()将会同时被调用。
# 然后greet()和welcome()函数在hi()函数之外是不能访问的,比如

  结果:

现在在hi()里面运行
现在在greet()里面运行
现在在welcom()里面运行
现在你返回到了hi()里面

  

 3)从函数中返回函数

def hi(name="yasoob"):def greet():return "now you are in the greet() function"def welcome():return "now you are in the welcome() function"if name == "yasoob":return greetelse:return welcomea = hi()
print(a)
#outputs: <function greet at 0x7f2143c01500>#上面清晰地展示了`a`现在指向到hi()函数中的greet()函数
#现在试试这个print(a())
#outputs: now you are in the greet() function

  注意下面的 hi()返回的值是greet,加上后面的括号时,就成为了greet()随即开始运行

 hi()() #这会输出 now you are in the greet() function。

  

 4)将函数作为参数传递给另外一个函数

def hi():return "hi yasoob!"def doSomethingBeforeHi(func):print("I am doing some boring work before executing hi()")print(func())doSomethingBeforeHi(hi)    #注意不要加括号
#outputs:I am doing some boring work before executing hi()
#        hi yasoob!

  

第一个修饰器

def a_new_decorator(a_func):def wrapTheFunction():print('我在a_func执行前做一些事情')a_func()print('我在a_func执行后做一些事情')return wrapTheFunction  #记得把这个内定义的函数返回def a_function_requiring_decoration():  #定义一个函数,等会用修饰器来修饰print('我是需要用修饰器修饰的函数')#使用修饰器
a_function_requiring_decoration=a_new_decorator(a_function_requiring_decoration)
a_function_requiring_decoration()

  结果:

我在a_func执行前做一些事情
我是需要用修饰器修饰的函数
我在a_func执行后做一些事情

  

  另一种生成被装饰函数的方法:用@

def a_new_decorator(a_func):def wrapTheFunction():print('我在a_func执行前做一些事情')a_func()print('我在a_func执行后做一些事情')return wrapTheFunction  #记得把这个内定义的函数返回#不同之处在这里
@a_new_decorator
def a_function_requiring_decoration():  #定义一个函数,等会用修饰器来修饰print('我是需要用修饰器修饰的函数')a_function_requiring_decoration()

  

解决被修饰的函数会被重命名问题的wraps函数

  使用上面会出现一个问题,获取_name_时会返回被修饰器内置函数的名字

print(a_function_requiring_decoration.__name__)
# Output: wrapTheFunction  应该返回a_function_requiring_decoration

之所以返回的是修饰器里内置的名字,是因为它会重写函数的名字和注释文档

而python提供了 functools.wraps() 来解决这个办法,以如下代码为例说明 functolls.wraps 使用方法

from functools import wrapsdef a_new_decorator(a_func):@wraps(a_func)def wrapTheFunction():---snip---    return a_funcreturn wrapTheFunction@a_new_decorator
def a_function_requiring_decoration():---snip--print(a_function_requiring_decoration.__name__)
# Output: a_function_requiring_decoration

@wraps 接受一个被修饰函数的名字,并加入了复制函数名称、注释文档、参数列表等功能,这让我们能在修饰器里访问函数被修饰之前的属性

怎样为修饰器传入参数:

  假如 a_function_requiring_decoration() 需要参数

def a_function_requiring_decoration(name):--snip--

  我们需要在定义 wrapTheFunction() 时指定参数即:

def wrapTheFunction(name):---snip---return a_func(name)

  当装饰器不知道要装饰的函数有多少个参数时,可以用 *args 来代替

def wrapTheFunction(*args):---snip---return a_func(*args)

  当需要关键字参数时

def a_function_requiring_decoration(name, age=None, height=None): print("I am %s, age %s, height %s" % (name, age, height))

  可以这样

def wrapTheFunction(*args, **kwargs): # args是一个数组,kwargs一个字典 logging.warn("%s is running" % func.__name__) return func(*args, **kwargs)

  

原文链接 >>>点击<<<

转载于:https://www.cnblogs.com/Gaoqiking/p/10470407.html

python 进阶:修饰器的介绍相关推荐

  1. 图解Python多修饰器时哪个先起作用

    修饰器本质上是一个函数,它接收一个函数作为参数并返回一个修饰过的新函数,一般来说不会改变函数的功能,只是在外围增加一些辅助性的检查或小功能. 在拙作<Python程序设计开发宝典>中有下面 ...

  2. Python使用修饰器强制函数只接收关键参数

    前面发过一篇文章介绍了单独一个星号或斜线作为函数参数的含义,请查看:Python函数中单独一个星号或斜线作为形参的含义 如果需要强制函数的所有参数都必须以关键参数形式进行传值,可以在定义函数时把单独一 ...

  3. python 函数修饰器 父类_手把手教你学python第十四讲(函数装饰器,super用法和时间处理)...

    文中有些字在图中是因为每篇文章最多100张图片,我把有的小图片和文字一起截图了,文中所有的引用都会标出原文网址,除此以外都是作者原创. 有时候会在文章最前或者最后补充一些知识或者把前面说的有问题的地方 ...

  4. python类修饰器_《Python有什么好学的》之修饰器

    "Python有什么好学的"这句话可不是反问句,而是问句哦. 主要是煎鱼觉得太多的人觉得Python的语法较为简单,写出来的代码只要符合逻辑,不需要太多的学习即可,即可从一门其他语 ...

  5. python函数修饰器_Python函数装饰器指南

    Python 具有强大的功能和富有表现力的语法.我最喜欢的装饰之一.在设计模式的上下文中,装饰器动态更改方法或类功能,而不必直接使用子类.当您需要扩展功能,但不想修改原函数时,这是理想的选择.我们可以 ...

  6. python自定义修饰器_Python概述

    #Version 3.0 本章主要解决:为什么学Python,Python是什么样的语言,怎么学Python,怎样做老庄才给你及格或优秀. 一.为什么学Python 学习编程要比学习英语更重要,因为编 ...

  7. Python中修饰器的定义与使用

    修饰器(decorator)是函数嵌套定义的另一个重要应用.修饰器本质上也是一个函数,只不过这个函数接收其他函数作为参数并对其进行一定的改造之后使用新函数替换原来的函数.修饰器的主要应用场合是定义多个 ...

  8. python进阶装饰器_Python进阶: 通过实例详解装饰器(附代码)

    Python中的装饰器有很多用处,比如输出日志.参数检查.代理设置.计数计时.结果缓存等等.本文就通过几个装饰器例子,详细解释一下Python中装饰器的用法.一步步从简到繁学习装饰器用法 其他一些装饰 ...

  9. Python多版本管理器-pyenv 介绍及部署记录

    一. pyenv简单介绍 在日常运维中, 经常遇到这样的情况: 系统自带的Python是2.x,而业务部署需要Python 3.x 环境, 此时需要在系统中安装多个Python版本,但又不能影响系统自 ...

最新文章

  1. VGG卷积神经网络模型加载与运行
  2. RAID之中的RAID5的创建及示例
  3. nginx proxy_next_upstream导致的一个重复提交错误
  4. 设置代码ios中根据文本设置label高度设置代码
  5. WINCE恢复默认HIVE注册表的方法
  6. Unreal Engine 4 —— 使用ProceduralMeshComponent实现模型实时切割
  7. 关于Aspose对于Word操作的一些扩展及思考
  8. 库克谈iPhone 12供应紧张问题;2020中国互联网百强名单:阿里、腾讯、美团分列前三;Dgraph新版发布|极客头条
  9. web.config中特殊字符的处理
  10. python-Error Message: 'float' object cannot be interpreted as an integer
  11. tekla钢结构算量_Tekla有用吗?Tekla软件在钢结构项目中有什么作用?
  12. 傅里叶光学 matlab,基于MATLAB的傅里叶光学实验的计算机模拟
  13. 5.郝斌C语言笔记——运算符
  14. 考教师资格证需要买书吗?
  15. 手机的RFID射频技术应用
  16. 基础的重要性(程序员之路)
  17. Sub Matrix Sum 含负数的最短区间+ 矩阵一维化
  18. 周报—FPGA(浩子)
  19. 二进制转bcd码c语言程序,二进制转8421BCD码的算法
  20. 一盒两用——破解移动IPTV机顶盒为两用安卓机顶盒

热门文章

  1. Cloud Native概念
  2. Javascript学习--------详解window窗口对象
  3. Javascript调试技巧整理
  4. 微软一顿操作猛如虎,PowerShell排名直线上升
  5. redis报错Windows error 0x70--记录一次服务器雪崩异常
  6. 1562. [NOI2009]变换序列【二分图】
  7. DS实验题 Floyd最短路径 Prim最小生成树
  8. 【CURL】模拟登录网站并获取用户信息
  9. linux下vi命令修改文件及保存的使用方法
  10. Eclipse和PyDev搭建完美Python开发环境(Windows篇)(转)