最近在看 flask的视图装饰器 时,忽然想起预(复)习一下python的装饰器.

这里有一篇比较好的讲解装饰器的书写的 Python装饰器学习(九步入门) .

这里不单独记录装饰器的书写格式了,重点是工作流程.

首先常见的 装饰器 格式就是通过@语法糖,简便的写法,让流程有些不太清楚.

装饰器不带参数的情况下:

def deco(func):

def _deco():

print("before myfunc() called.")

func()

print("  after myfunc() called.")

return _deco

@deco

def myfunc():

print(" myfunc() called.")

myfunc()

运行结果:

before myfunc() called.

myfunc() called.

after myfunc() called.

myfunc() called.

这个@语法糖的作用是:

def myfunc():

print(" myfunc() called.")

myfunc = deco(myfunc)

也就是现在的myfunc不再是一开始定义的那个了,而变成了

def _deco():

print("before myfunc() called.")

func()

print("  after myfunc() called.")

这一点可以通过

print myfunc.__name__

而复杂一点的,装饰器带参数的,如:

def deco(arg="haha"):

def _deco(func):

def __deco():

print("before %s called [%s]." % (func.__name__, arg))

func()

print("  after %s called [%s]." % (func.__name__, arg))

return __deco

return _deco

@deco()#注意有括号

def myfunc():

print(" myfunc() called.")

@deco("haha1")

def myfunc1():

print(" myfunc() called.")

myfunc()

myfunc1()

实际的操作是,先把装饰进行了运算,即函数deco先被调用

等效于:

def _deco(func):

def __deco():

print("before %s called [%s]." % (func.__name__, "haha"))# arg ==> "haha"

func()

print("  after %s called [%s]." % (func.__name__, "haha"))# arg ==> "haha"

return __deco

@d_deco#注意没有括号,第一处

def myfunc():

print(" myfunc() called.")

@_deco#这也没括号,第二处

def myfunc1():

print(" myfunc1() called.")

myfunc()

myfunc1()

而参数arg 使用的是默认的"haha

更直观的表达方式就是:

def deco(arg="haha"):

def _deco(func):

def __deco():

print("before %s called [%s]." % (func.__name__, arg))

func()

print("  after %s called [%s]." % (func.__name__, arg))

return __deco

return _deco

def myfunc():

print(" myfunc() called.")

def myfunc1():

print(" myfunc() called.")

myfunc = deco()(myfunc)

myfunc1 = deco("haha1")(myfunc1)

这时再来看标准库functools中的wraps的使用,比如官网例子:

from functools import wraps

def my_decorator(f):

@wraps(f)

def wrapper(*args, **kwds):

print 'Calling decorated function'

return f(*args, **kwds)

return wrapper

@my_decorator

def example():

"""Docstring"""

print 'Called example function'

example()

print example.__name__

print example.__doc__

过程就是

def my_decorator(f):

def wrapper(*args, **kwds):

print 'Calling decorated function'

return f(*args, **kwds)

wrapper.__name__ = f.__name__

wrapper.__doc__  = f.__doc__

return wrapper

example = my_decorator(example)

这样就保留了原函数名称属性和doc,

标准库中函数wraps,可以这样理解:

def wraps(f):

def _f(*args,**kwargs):

f(*args,**kwargs)

_f.__name__ = f.__name

_f.__doc__  = f.__doc__

return _f

上面的wraps流程可以看出,如果直接使用wraps简直就是f = f(其实不能直接使用),所以一般都是如实例这样包藏在一个装饰器函数内部.

来源:oschina

链接:https://my.oschina.net/u/1755923/blog/495293

python中wraps_python 装饰器及标准库functools中的wraps相关推荐

  1. python中wraps_python装饰器函数wraps

    python的装饰器是python的重要特性之一,通过装饰器你能够在执行已有的操作的同时,去执行额外的操作.装饰器的主要作用在不改变原有函数或者类等内部的实现的前提下,对其进行功能的拓展.这是装饰器最 ...

  2. python中的装饰器有哪些-python 装饰器以及开发中常用的例子

    有时候我们想为多个函数,同意添加某一种功能,比如及时统计,记录日志,缓存运算结果等等,而又不想改变函数代码 那就定义装饰器函数,用它来生成一个在原函数基础添加了新功能的函数,代替原函数 参考金角大王的 ...

  3. python装饰器原理-python 中的装饰器及其原理

    装饰器模式 此前的文章中我们介绍过装饰器模式: 装饰器模式中具体的 Decorator 实现类通过将对组建的请求转发给被装饰的对象,并在转发前后执行一些额外的动作来修改原有的部分行为,实现增强 Com ...

  4. 为什么在Python代码中需要装饰器

    Python is praised for its clarity and syntactic sugariness. In this article, I will teach you to use ...

  5. python类装饰器详解-Python类中的装饰器在当前类中的声明与调用详解

    我的Python环境:3.7 在Python类里声明一个装饰器,并在这个类里调用这个装饰器. 代码如下: class Test(): xx = False def __init__(self): pa ...

  6. python 类装饰器和函数装饰器区别_python进阶之装饰器之4在类中定义装饰器,将装饰器定义为类,两者的区别与联系...

    # 把装饰器定义为类 # 定义中需要实现__call__(),__get__() 方法 import types from functools import wraps class Profiled: ...

  7. python中装饰器的使用教程详解(wraps)

    先看下面的函数简单理解一下 示例代码: import loggingdef use_logging(func):logging.error("%s is running" % fu ...

  8. 为什么说想到Python中的装饰器是天才

    为什么说想到Python中的装饰器是天才 只需一个@符号就能分析.测试和重复使用你的代码 带着魔杖的仙女在Python代码中飞舞 软件中有没有什么是神奇的小魔法? 有,装饰器却非常接近! 如果说有一件 ...

  9. Python中的装饰器是什么?装饰器是如何工作的?

    Python很早就引入了装饰器--在PEP-318中,作为一种简化函数和方法定义方式的机制,这些函数和方法在初始定义之后必须进行修改. 这样做的最初动机之一是,使用classmethod和static ...

最新文章

  1. 看完这篇缓存双写分析,你面试不再有问题呢~
  2. .net 插件式开发学习总结
  3. The python debugger调试(PDB)的简介
  4. 浅谈android hook技术
  5. redis安装,主从集群
  6. Web Storage中的sessionStorage和localStorage
  7. React开发(167):...数组拼接
  8. 泄漏 iOS 关键源码的人,居然是苹果的一个实习生
  9. php 类似百度分页,写了一个仿百度贴吧分页效果的分页类,有人要么?
  10. Keil(MDK) 5 软件安装教程
  11. 数据结构_树状数组 详解
  12. IE 浏览器阻止打印页面的方法
  13. 自学单片机是否先学c语言,学习单片机需要先学好C语言再去学单片机吗
  14. 【机器学习】【决策树】自己动手用Python实现一个类:in样本集,out特征分布、概率密度、熵、条件熵、信息增益、信息增益比
  15. cnpm和npm使用,遇到的问题及解决方法
  16. 帆软报表决策系统忘记密码了,使用重置密码插件
  17. 绕口令:《舌头是怎样练成的》
  18. 万年历C语言程序可参考的文献,万年历的c语言程序
  19. 超级服装分床省料软件
  20. win10打开.md文件

热门文章

  1. springboot快速开发框架推荐,接私活利器
  2. C#中saveFileDialog的使用
  3. mysql escape的用法_#ORACLE 每日一点# ESCAPE用法
  4. SIFT原理及步骤详解
  5. centos7安装redis单机版(阿里云)
  6. 基于MATLAB的药物扩散仿真系统设计与实现 文档+上机实验报告+项目源码+运行说明
  7. getline的使用
  8. 宽带和流量是分开的吗_流量和宽带有什么区别-流量和宽带有什么区别?哪个划算?-综投网...
  9. 设计模式--第七章 克隆模式
  10. Spring Boot 启动事件和监听器,太强大了!